Try... Catch...? Finally...
Published: 2023-07-24 00:01:03

## Introduction

Whenever the phrase _"Try...? Catch..? Finally..."_ pops up in development discussions, I can't help but read it out humorously, as if someone is playfully asking, "Try this… caught anything? Finally, do this to it" (laughs). 
However, aside from my tagging it as humorous, this phrase encapsulates a very useful, powerful, and strong concept in JavaScript development. The phrase represents a remarkable and exceptional way of fortifying (if I can use that word :) ) our codes against errors. In this piece, we embark on an all-expense-paid trip (laughs) to explore and comprehend how the trio of try-catch-finally blocks is significant in development. 
We will delve into how they effectively empower developers to handle exceptions, their role in effective error handling, and why it's surprising how often they are underutilized in development.




## What are try-catch-finally blocks?

A try-catch-finally block is a construct in Javascript that provides developers a robust mechanism to better handle exceptions (errors) in their code, particularly during operations like API calls. The try block contains code that might throw exceptions, whereas the catch block gracefully captures and handles these exceptions. The optional finally block, on the other hand, executes the code in its block regardless of the outcome of either of the blocks. With that, a Developer has a better structure and a controlled way to handle exceptions/errors and do necessary cleanup operations.

### The `try` block

```javascript
try{
// try something - like getting list of users
}
```

### The `catch` block

```javascript
catch(e){
// caught some errors? do something with it here - log or maybe send a custom toast notification
}
```

### The `finally` block

```javascript
finally{
// do something after try and catch block regardless of the response from there.
}
```

### Sample Code: The `trio` in action

```javascript
async function fetchDataFromAPI(url) {
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error('Failed to fetch data from the API.');
      }
      const data = await response.json();
      // Process the data and return the result.
      return data;
    } catch (error) {
      // Handle the exception/error gracefully.
      console.error('Error occurred while fetching data:', error.message);
      // Optionally, you can handle the error in other ways, such as showing a user-friendly message via a toast notification package
    } finally {
      // Perform cleanup operations, if any, regardless of the outcome of try or catch blocks.
      console.log('API call completed.');
    }
  }
```


## Importance of Using `try-catch-finally` blocks

The try-catch block plays a vital role in JavaScript development for numerous reasons. Firstly, as earlier mentioned, it creates a sophisticated and effective way of identifying and handling errors/exceptions by wrapping error-prone code with the blocks, thereby shielding developers from code crashes during unexpected situations, ensuring users are not left frustrated. Additionally, the try-catch block contributes to the stability of applications. Aside from taking away the possibility of application crashes, it enables the handling of specific types of exceptions and renders appropriate error handling techniques. That includes giving meaningful error messages to users and logging issues for easier debugging. Frameworks like React greatly benefit from try-catch-finally blocks, especially when executing fetch requests alongside the built-in React state manager like useState. Furthermore, the optional finally block proves valuable in resetting loading states, preventing the rendering of unused states, and enhancing performance.

A very good example is in resetting loading states in React in order to stop the rendering of unused states:

```javascript
async function fetchDataFromAPI(url) {
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error('Failed to fetch data from the API.');
      }
      const data = await response.json();
      // Process the data and return the result.
      return data;
    } catch (error) {
      // Handle the exception/error gracefully.
      console.error('Error occurred while fetching data:', error.message);
      // Optionally, you can handle the error in other ways, such as showing a user-friendly message via a toast notification package
    } finally {
      // Perform cleanup operations, if any, regardless of the outcome of try or catch blocks.
      console.log('API call completed.');
    }
  }
```


The above example is a component for rendering a Dashboard - the sample function is meant to fetch a list of Users and save it to a `state` named `users`. 
- The function starts with setting the `loading` state to `true` thereby triggering the `loading animation` `<MoonLoader />`
- At the `catch` block we get hold of exceptions or errors and right now we only `log` it to the browser console.
- At the finally block, the `loading` state from React's `useState` is reset to `false` and this is regardless of the response in `try or catch` blocks.



## Common mistakes and misconceptions: 

Despite its importance, many developers have failed to utilize the try-catch-finally construct effectively. One common mistake is having excessive code within the blocks. It is very important to identify specific sections of your code that need the implementation of the blocks. Another misconception is neglecting the optional block in the trio, the finally block. Developers often forget to perform cleanup operations and how vital the finally block is at executing such seamlessly, such as reallocating memory, resetting loading states, or closing opened states amongst other things to avoid leaks and improve performance.
Let's consider a real-world example like the code above, if that is a Dashboard component for your Web application that makes an API call to get and render list of Users in your platform. By using try-catch-finally blocks, you can gracefully handle scenarios where the API request fails due to network issues. You can display a user-friendly error message to the user, log the error for troubleshooting, and ensure that the application remains functional despite the failure.



## Conclusion:

Try-Catch-Finally constructs are important tools in error handling, avoiding leaks and improving performances in JavaScript development. They give developers an easy to implement ground for handling exceptions, catching specific error messages and handling cleanup operations. By following the best practices and utilizing these constructs effectively, Developers can ensure robustness & reliability of their code. Embrace that power and let your code glitter!