Skip to content

Instantly share code, notes, and snippets.

@joedooley
Forked from justmoon/custom-error.js
Created November 16, 2020 16:46
Show Gist options
  • Select an option

  • Save joedooley/248a850932d1f76a187b5ad744929f69 to your computer and use it in GitHub Desktop.

Select an option

Save joedooley/248a850932d1f76a187b5ad744929f69 to your computer and use it in GitHub Desktop.

Revisions

  1. @justmoon justmoon revised this gist Feb 1, 2015. 2 changed files with 18 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions custom-error.js
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,10 @@
    module.exports = CustomError;
    'use strict';

    function CustomError(message, extra) {
    Error.call(this);
    module.exports = function CustomError(message, extra) {
    Error.captureStackTrace(this, this.constructor);
    this.name = this.constructor.name;
    this.message = message;
    this.extra = extra;
    }
    };

    require('util').inherits(CustomError, Error);
    require('util').inherits(module.exports, Error);
    14 changes: 14 additions & 0 deletions error.md
    Original file line number Diff line number Diff line change
    @@ -11,3 +11,17 @@ function doSomethingBad() {
    throw new CustomError('It went bad!', 42);
    }
    ```

    ### Features

    * **Name appears once** - less editing if you have to create lots of custom error classes
    * **Easy to subclass** - just change the last line to inherit from another custom error class you created
    * **Correct stack trace** - no extra stack frames, no double capturing of the stack trace

    ### Anti-patterns

    These are some things that I've seen in other proposed solutions that you should avoid.

    * `Error.call(this)` - creates another error object (wasting a bunch of time) and doesn't touch `this` at all
    * `Error.captureStackTrace(this, arguments.callee);` - works, but `arguments.callee` is deprecated, so don't use it
    * `this.stack = (new Error).stack` - this... I don't even...
  2. @justmoon justmoon revised this gist Feb 1, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions error.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    It's nice to be able to distinguish error types by classes. But it's a bit tricky to correctly create a custom error class in Node.js, so here is an example.

    This example also shows how to add an extra parameter called `extra` that will be stored as a property on the error.
    The example also shows how to add an extra parameter called `extra` that will be stored as a property on the error.

    Example usage:
    ### Usage

    ``` js
    var CustomError = require('./errors/custom-error');
  3. @justmoon justmoon revised this gist Feb 1, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion error.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Sometimes you want to wrap error objects with application-specific errors for your stack traces.
    It's nice to be able to distinguish error types by classes. But it's a bit tricky to correctly create a custom error class in Node.js, so here is an example.

    This example also shows how to add an extra parameter called `extra` that will be stored as a property on the error.

  4. @justmoon justmoon revised this gist Feb 1, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions error.md
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ Example usage:
    ``` js
    var CustomError = require('./errors/custom-error');

    function doSomethingRisky(callback) {
    throw new CustomError('You lost!', 42);
    function doSomethingBad() {
    throw new CustomError('It went bad!', 42);
    }
    ```
  5. @justmoon justmoon revised this gist Feb 1, 2015. 1 changed file with 43 additions and 0 deletions.
    43 changes: 43 additions & 0 deletions test-error.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    // Mini test suite for our custom error

    var assert = require('assert');
    var CustomError = require('./errors/custom-error');

    function doSomethingBad() {
    throw new CustomError('It went bad!', 42);
    }

    try {
    doSomethingBad();
    } catch (err) {
    // The name property should be set to the error's name
    assert(err.name = 'CustomError');

    // The error should be an instance of its class
    assert(err instanceof CustomError);

    // The error should be an instance of builtin Error
    assert(err instanceof Error);

    // The error should be recognized by Node.js' util#isError
    assert(require('util').isError(err));

    // The error should have recorded a stack
    assert(err.stack);

    // toString should return the default error message formatting
    assert.strictEqual(err.toString(),
    'CustomError: It went bad!');

    // The stack should start with the default error message formatting
    assert.strictEqual(err.stack.split('\n')[0],
    'CustomError: It went bad!');

    // The first stack frame should be the function where the error was thrown.
    assert.strictEqual(err.stack.split('\n')[1].indexOf('doSomethingBad'), 7);

    // The extra property should have been set
    assert.strictEqual(err.extra, 42);
    }

    // Spoiler: It passes!
  6. @justmoon justmoon revised this gist Feb 1, 2015. 2 changed files with 18 additions and 20 deletions.
    11 changes: 11 additions & 0 deletions custom-error.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    module.exports = CustomError;

    function CustomError(message, extra) {
    Error.call(this);
    Error.captureStackTrace(this, this.constructor);
    this.name = this.constructor.name;
    this.message = message;
    this.extra = extra;
    }

    require('util').inherits(CustomError, Error);
    27 changes: 7 additions & 20 deletions error.md
    Original file line number Diff line number Diff line change
    @@ -1,26 +1,13 @@
    Sometimes you want to wrap error objects with application-specific errors for your stack traces.

    Your custom error constructor:

    ```
    function CustomError(e, extra) {
    Error.call(this);
    Error.captureStackTrace(this, CustomError);
    this.id = e.id;
    this.name = 'CustomError';
    this.message = e.message
    }
    require('util').inherits(CustomError, Error);
    ```
    This example also shows how to add an extra parameter called `extra` that will be stored as a property on the error.

    Example usage:

    function doWork(callback) {
    doErrorProneWork(funtion(err, result) {
    if (err) return callback(new CustomError(err));

    ...
    }
    }
    ``` js
    var CustomError = require('./errors/custom-error');

    function doSomethingRisky(callback) {
    throw new CustomError('You lost!', 42);
    }
    ```
  7. @subfuzion subfuzion created this gist Feb 26, 2014.
    26 changes: 26 additions & 0 deletions error.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    Sometimes you want to wrap error objects with application-specific errors for your stack traces.

    Your custom error constructor:

    ```
    function CustomError(e, extra) {
    Error.call(this);
    Error.captureStackTrace(this, CustomError);
    this.id = e.id;
    this.name = 'CustomError';
    this.message = e.message
    }
    require('util').inherits(CustomError, Error);
    ```

    Example usage:

    function doWork(callback) {
    doErrorProneWork(funtion(err, result) {
    if (err) return callback(new CustomError(err));

    ...
    }
    }