overleaf/libraries/o-error
2020-04-29 21:03:41 +01:00
..
.circleci Add linting and formatting 2020-04-17 09:14:35 +01:00
test Add typescript for type checking 2020-04-29 21:03:41 +01:00
.editorconfig Add linting and formatting 2020-04-17 09:14:35 +01:00
.eslintrc.json Add typescript for type checking 2020-04-29 21:03:41 +01:00
.gitignore
.prettierrc.json Add linting and formatting 2020-04-17 09:14:35 +01:00
http.js Make constructor take only message and info 2020-04-17 15:45:08 +01:00
index.js Make constructor take only message and info 2020-04-17 15:45:08 +01:00
LICENSE Tidy up for release 2018-04-23 08:11:08 +01:00
package-lock.json Add typescript for type checking 2020-04-29 21:03:41 +01:00
package.json Add typescript for type checking 2020-04-29 21:03:41 +01:00
README.md Apply linting rules 2020-04-17 09:14:35 +01:00

@overleaf/o-error

CircleCI

Make custom error classes that:

  • pass instanceof checks,
  • have stack traces,
  • support custom messages and properties (info), and
  • can wrap internal errors (causes) like VError.

ES6 classes make it easy to define custom errors by subclassing Error. Subclassing OError adds a few extra helpers.

Usage

Throw an error directly

const OError = require('@overleaf/o-error')

function doSomethingBad() {
  throw new OError({
    message: 'did something bad',
    info: { thing: 'foo' },
  })
}
doSomethingBad()
// =>
// { OError: did something bad
//    at doSomethingBad (repl:2:9) <-- stack trace
//    name: 'OError',              <-- default name
//    info: { thing: 'foo' } }     <-- attached info

Custom error class

class FooError extends OError {
  constructor(options) {
    super({ message: 'failed to foo', ...options })
  }
}

function doFoo() {
  throw new FooError({ info: { foo: 'bar' } })
}
doFoo()
// =>
// { FooError: failed to foo
//    at doFoo (repl:2:9)      <-- stack trace
//    name: 'FooError',        <-- correct name
//    info: { foo: 'bar' } }   <-- attached info

Wrapping an inner error (cause)

function doFoo2() {
  try {
    throw new Error('bad')
  } catch (err) {
    throw new FooError({ info: { foo: 'bar' } }).withCause(err)
  }
}

doFoo2()
// =>
// { FooError: failed to foo: bad   <-- combined message
//     at doFoo2 (repl:5:11)        <-- stack trace
//   name: 'FooError',              <-- correct name
//   info: { foo: 'bar' },          <-- attached info
//   cause:                         <-- the cause (inner error)
//    Error: bad                    <-- inner error message
//        at doFoo2 (repl:3:11)     <-- inner error stack trace
//        at repl:1:1
//        ...

try {
  doFoo2()
} catch (err) {
  console.log(OError.getFullStack(err))
}
// =>
// FooError: failed to foo: bad
//     at doFoo2 (repl:5:11)
//     at repl:2:3
//     ...
// caused by: Error: bad
//     at doFoo2 (repl:3:11)
//     at repl:2:3
//     ...

References