In the catch block, we can get information about the error that the object represents.
All errors that are generated JavaScript interpreter provide an object of type Error, which has a number of properties:
- message – error message
- name – error type
- fileName – the name of the JavaScript code file where the error occurred (not in all browsers)
- lineNumber – the line in the file where the error occurred
- columnNumber – the column in the row where the error occurred
- stack – error stack
Let’s get these errors, for example, when calling a non-existent function:
try { callSomeFunc(); } catch (error) { console.log("Error type:", error.name); console.log("Error name:", error.message); }
Error types
We saw above that the error generated by the interpreter is of type Error, but calling a non-existent function generates an error of type ReferenceError. This is because the Error type represents a general type of error. In the same time There are specific types of errors for certain situations:
- EvalError – represents an error that is generated when executing a global function eval()
- RangeError – an error is generated if the parameter or variable represents a number that is out of some valid range
- ReferenceError – an error is generated when accessing a non-existent link
- SyntaxError – represents a syntax error
- TypeError – an error is generated if the value of a variable or parameter is of the wrong type, or if an attempt is made to change a value that cannot be changed
- URIError – an error is generated when invalid values are passed to the encodeURI() and decodeURI() functions
- AggregateError – provides an error that concatenates multiple errors that have occurred
When generating errors, we can use built-in error types:
class Person { constructor(pName, pAge) { const age = parseInt(pAge); if (isNaN(age)) throw new TypeError("Age must be greater than 0"); if (age < 0 || age > 120) throw new RangeError("Age must be greater than 0 and less than 120"); this.name = pName; this.age = age; } print() { console.log(`Name: ${this.name} Age: ${this.age}`); } }
Handling multiple types of errors
Sometimes it is necessary to differentiate between the handling of different types of errors. In this case, we can check the type of error that occurred. For example, the example above with the Person class:
class Person { constructor(pName, pAge) { const age = parseInt(pAge); if (isNaN(age)) throw new TypeError("Age must represent a number"); if (age < 0 || age > 120) throw new RangeError("Age must be greater than 0 and less than 120"); this.name = pName; this.age = age; } print() { console.log(`Name: ${this.name} Age: ${this.age}`); } } try { const tom = new Person("Tom", -45); const bob = new Person("Bob", "not a number"); } catch (error) { if (error instanceof TypeError) { console.log("Incorrect data type"); } else if (error instanceof RangeError) { console.log("Invalid value"); } console.log(error.message); }
Creating custom error types
We are not limited to built-in error types and, if necessary, we can create our own error types:
class PersonError extends Error { constructor(value, ...params) { super(...params) this.name = "PersonError" this.argument = value; } } class Person { constructor(pName, pAge) { const age = parseInt(pAge); if (isNaN(age)) throw new PersonError(pAge, "Age must represent a number"); if (age < 0 || age > 120) throw new PersonError(pAge, "Age must be greater than 0 and less than 120"); this.name = pName; this.age = age; } print() { console.log(`Name: ${this.name} Age: ${this.age}`); } } try { const bob = new Person("Bob", "bla bla"); } catch (error) { if (error instanceof PersonError) { console.log("Person type error. Incorrect value:", error.argument); } console.log(error.message); }