goerr

handle throwing errors in golang way.

Usage no npm install needed!

<script type="module">
  import goerr from 'https://cdn.skypack.dev/goerr';
</script>

README

goerr CircleCI

handle throwing errors in golang way

Install

# install with npm
npm add goerr
# install with yarn
yarn add goerr

Import

// ES Module
import goerr from 'goerr'
// CommonJS
const goerr = require('goerr')

Usage

Handle A Synchronous Function Calling

goerr method expects a function (especially a lambda expression) as the argument, in which calling some throwable functions and returning a value.

The value will be the first element of an array returned by goerr. Any error throwed when calling the function will be the second element of the array.

Note: You can not return a Promise object in the throwableFunction. If you really want to handle asynchronous errors, see next part.

API

function goerr<T>(func: () => T): [T, Error]

Example

const [result, err] = goerr(() => throwableFunction())

if (err) {
  // do something here
}

// go ahead with the result
console.log(result)

Handle An Asynchronous Promise

goerr can aslo accept a Promise object in order to handle cases you have to do asynchronously.

API

function goerr<T>(promise: Promise<T>): Promise<[T, Error]>

Example

const [result, err] = await goerr(axios.get('https://example.com'))

if (err) {
  // do something here
}

// go ahead with the result
console.log(result)

Why This

Background

Since we all know that try/catch works good in JavaScript, you might be confused about if we really need to handle errors in golang way.

Suppose now we are writing a function to return a list coming from a throwable function, and we think returing an empty list when an error throwed would be better.

How could we do?

Solution 1

function listOf() {
  try {
    const list = throwable()
    return list
  } catch (_) {
    return []
  }
}

It looks good, but what if we need to do some operations on this list?

Solution 2

function listOf() {
  try {
    const list = throwable()

    for (let item of list) {
      // do something with items
    }

    return list
  } catch (_) {
    return []
  }
}

Good job! But if we have a better choise?

Solution 3

The defect of solution 2 is about code smell. We should return as soon as we can to avoid nested code.

function listOf() {
  const [list, err] = goerr(throwable)

  if (err) {
    return []
  }

  for (let item of list) {
    // do something with items
  }

  return list
}

Now you see the for loop becomes the top level of the function. It looks more clear, right?