# Make Your Try and Catch Bullet Proof

### WHY WE NEED TRY-CATCH


Exceptions are unwanted event that hinders our code execution.
They are all around us and can show up when you least expect them. 
It’s this uncertainty that makes it a headache for Developers in designing a robust application.

Javascript being a dynamically typed interpreted language may cause exceptions during execution which may be difficult to reproduce during the development stage.
Hence Exception handling becomes an important aspect of software development. 

To tackle this problem in javascript we have exception handling constructs like
`try-catch-finally`
These allow us to wrap our *potential* code that can throw an error or cause an exception which we can then handle in our `catch` block.

```js
      try {
        // Some exception prone code
      }
     catch(e) {
      // Handle exception
      }

```

Now I have been working with JS for the past 3 years now and I have come to this realization that the purpose and ideas behind the usage of try-catch weren’t actually getting fulfilled.


Sure you could wrap your code with `try-catch` and prevent your code to cause a runtime exception 
But that still leaves a blind spot in our exception handling scenario...

Let me explain my ideology and reasoning behind this.

### UNDERSTANDING THE PROBLEM 


It has a very loose syntax when it comes to bubbling up the error towards the caller function.
So Even if you make sure that one part of your code will not cause an exception 
There is no guarantee at the caller's end. 

A function is a `lazy entity`, which means that it will only execute when the function is called not when it is defined. 
So now the problem becomes evident.
Even though you have wrapped your function definition with `try-catch 
You have no control over how that function will be called 
And in which environment will it throw an error.

Here the control in case of try-catch is with the function Definition a
Not with a function call 

So In order to make this `try-catch` **bullet-proof** and more robust 
What we can do is make sure the point where the function is called Handles this exception state for us.
Then we can be sure when and how the function will behave and we can dictate the flow of error handling.

This is what I like to call **‘Inversion Of Control’**


Also if you are a fan of Declarative syntax like me, you would have noticed that try-catch is imperative and hence we better need an abstraction for that




### EXAMPLE

Let me explain how I achieved this goal with a simple example so that you get an actual idea of how it improves the existing solution
 
Now this is a very simple and common use-case example that I have taken 

Say we have our node development server setup and have some configuration settings that we want to read from a file 
Now we know that Reading From File always has a possibility of throwing an I/O error
So we wrap it with `try-catch`

This is how it will look -



```js
function getPortNumber() {
    try {
        const fileContent = fs.readFileSync('config.dev.json')
        const config = JSON.parse(fileContent)
        return config.port

    } catch (err) {
        return 3000
    }
}

```
At first glance it might look like normal and perfectly valid code but if you keep in mind the above-mentioned points that we discussed you’ll start to notice the shortcomings.

Let’s come towards the solution.

### DEVELOPING SOLUTION

We have 2 possible state paths for our code execution
Let’s call it Right and Left 

`Right` -> Makes sure we follow the normal flow of code

`Left `-> Short Circuits the code at the moment it is taking this branch
 
Now we know that to handle errors we must take `Left` whereas by default we go `Right`

To make this syntax Declarative I defined my Two Custom Chainable Box Types.
 
If you haven’t read my previous post on how to make these [Chainable Data types](https://bisu.hashnode.dev/chainable-ds) give it a quick read to understand the code examples given below



```js

const Right = x => ({
    map: f => Right(f(x)),
    fold: (_, g) => g(x),

})

```
```js

const Left = x => ({
    map: f => Left(x),
    fold: (f, _) => f(x),
})

```

Next, we need a `tryCatch` function so that we go on chaining on these different branches in a **declarative** and **pipelined** manner.
And inside that, we make decide the path we will follow 



```js
const tryCatch = f => {
    try {
        return Right(f())
    } catch (err) {
        return Left(err)
    }
}

```
Last but not least I like to have a separate function for reading from a file 
So let’s have that - 

```js
const readFile = path => tryCatch(() => fs.readFileSync(path))


```
Now that I have defined all these building blocks and laid the foundation for the solution,
It’s time to compose everything 

### Declarative Bulletproof designing of  Try-Catch -



```js

const getPortNumber_ = () =>
        readFile('config.dev.json')
        .map(JSON.parse)
        .map(({ port }) => port)


const resPort = getPortNumber_()
                .fold( () => 8080,  x => x )

console.log(resPort)
```

Here you can see how I can go on chaining new methods to my `getPortNumber_` because of my custom Data type that I have bound to without even having to think that it might blow up and throw an error or how to handle it there.

And finally, when I need to call the function I can chain `fold` function to it and provide how do I want to handle these 2 states

The first arg to fold is a function that handles the `Error / Left case`

And 2nd arg is a function that handles the `Success / Right case`

Thus we implemented what we wanted
We have designed an error handling pattern that has control on the function calling side thus giving us a way to write our code however we want and handle error cases during the function calls.

And this is how we achieve a better solution for Error Handling and a bullet-proof declarative `tryCatch`

Thanks for making it to the end!
I hope you learned something new and exciting today and maybe this post will inspire you to come up with your own better version of existing solutions :)

