Let’s Clean Up: Ugly Try-Catches in JavaScript!

Colum Ferry
Nov 30 · 3 min read
Photo by Caspar Camille Rubin on Unsplash

We’ve all been there. We have all used await on async methods, forgetting to wrap them in try-catch just to be told off about an Unhandled Error 😱

But it’s not just these aysnc methods that might throw. Perhaps we use a third-party library that throws, or we design our codebase in such a way that we throw errors intentionally to bubble error handling up a few layers.

So we proceed by wrapping our calls to the throwable methods in our try-catch blocks.

Perfect! 😍

🤔 Or is it?

Working in a code base where you can expect methods to throw can lead to situations where your logic is wrapped in try-catch blocks. It also leads to other code design problems.

Take a look at the examples below:

As we can see above, the myVar variable doesn't exist outside of the try block. But we need that value to continue our logic!!

So now we need to do something a little different.
How about:

🤮!

No. Let’s not do this.

Now all our logic wrapped inside the try block. That's ugly.
Also, if any of the subsequent method calls throw, are we sure we want to handle them the same way!? Possibly, but most likely not!

Ok, let’s try something else…

This is a little better, but still not perfect. It’s still ugly as myVar has to be declared then initialised almost immediately after just in a different scope. It also presents an issue when myThrowableMethod does throw, as execution will continue and try to use myVar!

🐛 Alert!

I could keep going, giving more situations where these try-catch blocks can present code design, readability, and maintainability problems.

Instead, I’ll present you with a solution!

The Solution 🚀

I wrote a small library to tackle this issue head on :

Let’s welcome no-try to the scene. 🎉

What is no-try? 😱

no-try is a tiny library that takes the try-catch out of your code, improves the readability and maintainability of your code whilst helping to improve code design.

It exposes two functions. noTry and noTryAsync with the latter resolving and returning the result of Promises.

Don’t believe me? Let’s look at it in more detail.

To install it, simply run npm i --save no-try

Then add it to your file:

In TypeScript:

import {noTry, noTryAsync} from "no-try";

In JavaScript:

const noTry = require('no-try').noTry;
const noTryAsync = require('no-try').noTryAsync;

Now, let’s refactor our example above to use no-try.

If you have a standard error handling function, you can supply that to noTry and it will invoke it for you if an error occurs!

And that’s it!

We’ve removed the try-catch blocks from our code, preventing issues relating to block-scoped variables, whilst also allowing our code to be much more readable without sacrificing the flexibility of handling the error how we want.

You can read more on no-try over on GitHub.

Now go clean your code!

If you have any questions, feel free to ask below or reach out to me on Twitter: @FerryColum.


Originally published at https://dev.to on November 30, 2019.

Learn the web's most important programming language.

Colum Ferry

Written by

JavaScript in Plain English
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade