Handle Javascript errors like in Go
Tags: javascript, intermediate, experiment
Published: 2022-08-11 15:00:02

---
title: Handle Javascript errors like in Go
published: true
description: I've experimented with error handling for Javascript async code. You'll see the usual, the not very common, and something unconventional. Hopefully this may be of use to someone.
tags: ["javascript", "intermediate", "experiment"]
canonical_url: https://ivanalejandro0.com/blog/javascript-errors-like-in-go/
---

## Introduction?
I feel like some patterns or shapes of error handling are more convenient than others. Depending on the context and what I needed to do when an exception occurred, I found myself handling errors differently.

And then I thought that it could be useful to write down the different ways of handling errors that I've been using and maybe experiment a bit with something new.

On this article I'll show you common ways of using data and errors, and then how I approached exception handling as is common in the Go programming language (disclaimer: I'm not a Go developer).

I'm going to be focusing on `async`/`Promise`s based code.

## Error handling, alt 1
```javascript
try {
  const data = await somethingThatCanFail()
  // do something with the `data`
} catch(error) {
  // handle the `error`
}
```
Most likely the most common way of handling error nowadays.

## Error handling, alt 2
```javascript
somethingThatCanFail()
  .then((data) => { /* do something with the `data` */ })
  .catch((error) => { /* do something with the `error` */ })
```
Nothing new here, on the contrary, the most common way of handling errors before `async`/`await` became mainstream.

## Error handling, alt 3
```javascript
try {
  await somethingThatCanFail()
    .then((data) => { /* do something with the `data` */ })
} catch(error) {
  // handle the `error`
}
```
This could be used on a way where you don't have to do much with the `data`, but you have to do more than a simple action to handle the `error`.

Note that even though we used `.then` we need `await`, otherwise if there's a problem `catch` won't get it.

## Error handling, alt 4
```javascript
const data = await somethingThatCanFail()
  .catch((error) => { /* do something with the `error` */ })
// do something with the `data`
```
This could be used on cases where you don't need to do much with the error, or where the `error` itself doesn't need to be accessed outside of the `catch` callback. It "saves" you from the extra nesting from the `try`/`catch` block, so it could help you handle problems more concisely.


## Error handling, idea
I don't think I've seen this approach anywhere, so I wanted to experiment on whether this "shape" made sense to me.

My idea is to borrow Go's approach of handling the error as a value, which is basically:

```go
f, err := os.Open("filename.ext")
if err != nil {
    log.Fatal(err)
}
// do something with the open *File f
```
You can read more about error handling in Go here: https://go.dev/blog/error-handling-and-go

I was picturing that the end result would be something like:

```javascript
const [data, error] = await somethingThatCanFail()
if (error) {
  // handle the `error`
}
```

Basically, we want our `Promise` to be turned into an `array`, we can do that like so:

```javascript
function promiseToArray(promise) {
   return promise
    .then(data => [data])
    .catch(error => [undefined, error]);
}

const [data, error] = await promiseToArray(somethingThatCanFail());
if (error) {
  // handle the `error`
}
```

So, we are kind of there, but I still don't like the syntax, let's try to improve this a bit...


```javascript
Promise.prototype.toGo = function() {
  return this
    .then(data => [data])
    .catch(error => [undefined, error]);
};

const [data, error] = await somethingThatCanFail().toGo();
if (error) {
  // handle the `error`
}
// or conversely
if (!error) {
  // do something with the `data`
}
```

Now I like it much better. We are modifying the `Promise` prototype, which may not be the best idea, but for an experiment looks great.

## Final thoughts
Should you use this? I don't know, probably not a good idea. Personally I'd rather stick to more commonly used patterns.

This approach could be useful for some specific use case, or maybe this idea will spark some other idea that will actually be useful.

## Disclaimer
While writing this, I found that someone already thought about this much earlier than me, check out this article:
https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/