Hello, everybody! ππΌ
In today's article we'll be talking about exceptions in JavaScript: what they are, different types, declaration and how to handle and deal with them appropriately.
First things first: Main concepts π§
Let's first have a look at the main concepts of exception handling to have a clear and concise idea of what they exactly mean in programming.
What is an exception? π«
An exception is an anomalous condition that breaks the regular execution of the code.
What does handle an exception mean? ππΌ
Exception handling is the method by which an exception is caught and managed.
Then, how can we handle exceptions in JavaScript? πΉ
To handle exceptions we'll use the try...catch statement provided by JavaScript.
As easy as that π
The try...catch statement π€
The try...catch statement is a block that tries to perform one or several actions that can lead to error conditions and defines the instructions to handle such errors appropriately in case they happen to occur.
Let's see the structure for this statement:
try{
/*
* Action(s) to be performed that can lead
* to an anomalous condition.
*/
}
catch(e){
/*
* Error / exception handling.
*/
}
finally{
/*
* Instruction(s) to be executed after
* the try...catch statement ends.
*/
}
Things to consider:
- Curly braces must be used anytime, even for one line statements within the blocks.
- A catch or a finally block must be defined as part of the try...catch statement, but neither of them are mandatory separately.
- The previous point results in the following types of try...catch statements:
- try...catch
- try...finally
- try...catch...finally
The throw statement π³
The throw statement, as its own name indicates, throws an exception when something wrong occurs within the function or block it is declared.
When a throw statement is found, the execution of the current function stops and the control is shifted to the catch block.
A very simple example:
try{
throw new Error('Something went wrong!');
}
catch(e){
console.error(e);
}
/*
* Output:
* Error: Something went wrong!
*/
A throw statement is usually called within the try block, but that doesn't mean that can't be called within a catch block (to rethrow an exception once it has been caught) or a finally block (to throw an exception no matter which previous block has been executed).
β«οΈ Rethrowing an exception in the catch block:
try{
try{
throw new Error('π');
}
catch(e){
console.error(e);
throw e;
}
}
catch(e){
console.error(e);
}
/*
* Output:
* Error: π
* Error: π
*/
β«οΈ Throwing an exception in the finally block:
try{
try{
throw new Error('Error - try block');
}
catch(e){
console.error(e);
throw new Error('Error - catch block'); //Note that this exception is never caught
}
finally{
throw new Error('Error - finally block');
}
}
catch(e){
console.error(e);
}
/*
* Output:
* Error: Error - try block
* Error: Error - finally block
*/
User-defined exceptions π¨π»βπ»π©π»βπ»
A user-defined exception is a custom exception that can contain any valid expression.
The following statements are all correct:
throw 'Error!';
throw 404;
throw false;
Let's see an example where an object is thrown.
Note that object properties become accessible once the exception is caught, through the error itself:
const UserException = {
name: 'UserException',
message: 'There was an error π'
}
try{
throw UserException;
}
catch(e){
console.error(`${e.name}: ${e.message}`);
}
/*
* Output:
* UserException: There was an error π
*/
JavaScript built-in errors can also be used as objects for user-defined exceptions and be thrown accordingly.
Take a look at the following example, where a TypeError error is thrown if the type of the required value is not String.
const TypeException = function(){
const msg = 'There was an error regarding the data type.';
this.error = new TypeError(msg);
}
const isString = value => typeof value === 'string';
const city = {};
const setCity = cityName => {
if(isString(cityName)) city.name = cityName;
else throw new TypeException();
}
try{
setCity(28);
console.log('--- City name has been set correctly.---')
}
catch(e){
console.error(e.error);
}
finally{
console.log('--- The execution has finished ---');
}
/*
* Output:
* TypeError: There was an error regarding the data type.
* --- The execution has finished. ---
*/
Conditional catch blocks π
There may be occasions where the try...catch block throws different types of exceptions.
In order to handle each of them in a proper way, we can use if...else statements within the catch block.
let month;
const setMonth = monthValue => {
if(typeof monthValue !== 'number') throw new TypeError(monthValue);
if(monthValue <= 0 || monthValue > 12) throw new RangeError(monthValue);
month = monthValue;
}
try{
setMonth(-5);
console.log(`-- Month ${month} has been set correctly ---`);
}
catch(e){
const errorInfo = 'Please enter a number [1-12]';
if(e instanceof TypeError)
console.error(`Wrong data type: ${e.message}. ${errorInfo}.`);
if(e instanceof RangeError)
console.error(`Out of range: ${e.message}. ${errorInfo}.`);
}
/*
* Output:
* Out of range: -5. Please enter a number [1-12].
*/
We could also use a switch statement to handle multiple exceptions, being both examples equivalent:
...
try{
setMonth(-5);
console.log(`-- Month ${month} has been set correctly ---`);
}
catch(e){
const errorInfo = 'Please enter a number [1-12]';
switch(e.name){
case 'TypeError':
console.error(`Wrong data type: ${e.message}. ${errorInfo}.`);
case 'RangeError':
console.error(`Out of range: ${e.message}. ${errorInfo}.`);
}
}
/*
* Output:
* Out of range: -5. Please enter a number [1-12].
*/
Summary: key points π«
- Exceptions are error conditions that break the normal flow of the code execution.
- An exception can be any kind of expression: a number, a string, an object...
- Exceptions should be thrown and handled appropriately in order to not crash the app and let the user know that something didn't go as expected.
- JavaScript built-in errors can be used as throwable objects for user-defined exceptions.
- Multiple exceptions can be handled within the same catch block.
β‘οΈ Related post on Instagram:
And that's all for today! π
A big thanks for reading π€ and don't hesitate to reach out to me if you have any questions or doubts about today's article.
I hope you found this article useful and I see you all in the next ππΌ
π Don't forget to follow @underscorecode on Instagram and Twitter for more daily webdev content: info, challenges, quizzes & more π
And last but not least... A quick friendly reminder before we go π
We all know there are million ways to get things done when it comes to programming and development, and we're here to help and learn, so, if you know another possible way to do what others are sharing (not better, not worse, just different), feel free to share it if you feel like it, but, please, always be kind and respectful with the author and the rest of the community. Thank you and happy coding!
Top comments (0)