Handling exceptions in JavaScript : Key points ⭐️
Tags: javascript, webdev, codenewbie, programming
Published: 2021-09-24 12:13:57

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: 

```js
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: 
```js
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:


```js
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:


```jsx
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:

```js
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:

```js
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_.

```js
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.

```js
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:

```js
...
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:

{% instagram CTCVoSDjH9t %}
____
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.

![Rachel Green from Friends TV Show behind a desk saying "Ask me anything"](https://media.giphy.com/media/XFuQ4InwtXBE4DDPHM/giphy.gif)

I hope you found this article useful and I see you all in the next 👋🏼

___

🎉 Don't forget to follow @underscorecode on [Instagram](https://instagram.com/underscorecode) and [Twitter](https://twitter.com/underscorecode) 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!