DEV Community

Max Frolov
Max Frolov

Posted on • Edited on

JavaScript error handling pattern tip

Don't throw a new Error(msg) if you not sure you handle it everywhere you use a module. It can break your app and it's not ideal UX for a user. You can follow the Either pattern from FP to avoid such situations.

// success and error cases
Success: { _tag: "Right", right: "Success data" }
Error: { _tag: "Left", left: "Error message" }

// helpers to define right or left value
export const isLeft = (left) => {
  switch (left._tag) {
    case 'Left':
      return true
    case 'Right':
      return false
  }
}

export const isRight = (right) => !isLeft(right)

export const right = (right) => ({ _tag: "Right", right })

export const left = (left) => ({ _tag: "Left", left })

// simple usage
import * as E from 'helpers/either'

const success = E.right("some value")
const error = E.isLeft("some error")

console.log(isRight(success) && success.right) // "some value"
console.log(isLeft(error) && error.left) // "some error"

Top comments (2)

Collapse
 
vonheikemen profile image
Heiker

If you're going to use tags and helper functions, why not go for a little pattern matching too?

function match(value, patterns) {
  const { type = null } = value || {};
  const _match = patterns[type];

  if(typeof _match == 'function') {
    return _match(value.data);
  } else if (typeof patterns._ == 'function') {
    return patterns._();
  }
  else {
    return;
  }
}

function Union(types) {
  return types.reduce((target, type) => {
    target[type] = (data) => ({
      type,
      data,
      match: patterns => match({type, data}, patterns)
    });
    return target;
  }, {});
}

Then you can have this.

const Result = Union(['Ok', 'Err']);
const something = Result.Ok({ stuff: 'good stuff' });
const maybe = Result.Err('this is still data');

something.match({
  Ok: ({stuff}) => `the ${stuff}`,
  Err: (msg) => msg,
  _: () => 'What?'
});

// the good stuff

For a better version of that checkout this library.

Collapse
 
max_frolov_ profile image
Max Frolov

Thanks for the suggestion, nice lib :) I use FP-TS and the pattern above is an abstract demonstration of the way of thinking