Skip to content

Instantly share code, notes, and snippets.

@logicalparadox
Created January 8, 2012 07:01

Revisions

  1. logicalparadox revised this gist Jan 8, 2012. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions About.md
    Original file line number Diff line number Diff line change
    @@ -6,8 +6,6 @@ I am working on a custom error constructor for my [seed](https://github.com/qual
    * When in development, I can easily throw these errors should I need additional feedback on to what is going on.
    * Any addon plugins made can use or extend the custom error type and still satisfy the first two objective with ease.

    This is still a work in progress. Comments encouraged. If you fork, please comment on your progress.

    [![Screenshot](http://f.cl.ly/items/2s0Z152a2W0A0K3x1m2p/CustomError.png)](http://cl.ly/1V3M1q3W0g422003271a)

    Technically inspired by [this post](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/).
  2. logicalparadox revised this gist Jan 8, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion customerror.js
    Original file line number Diff line number Diff line change
    @@ -83,6 +83,6 @@ CustomError.prototype.toJSON = function () {
    name: this.name
    , message: this.message
    , memory: this.memory
    , stack: this.stackJSON
    , stack: this._stack
    };
    }
  3. logicalparadox created this gist Jan 8, 2012.
    13 changes: 13 additions & 0 deletions About.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    # Custom Errors

    I am working on a custom error constructor for my [seed](https://github.com/qualiancy/seed) project. I had a few objectives in mind when I started.

    * When in production, these errors need to be able to be serialized for logging.
    * When in development, I can easily throw these errors should I need additional feedback on to what is going on.
    * Any addon plugins made can use or extend the custom error type and still satisfy the first two objective with ease.

    This is still a work in progress. Comments encouraged. If you fork, please comment on your progress.

    [![Screenshot](http://f.cl.ly/items/2s0Z152a2W0A0K3x1m2p/CustomError.png)](http://cl.ly/1V3M1q3W0g422003271a)

    Technically inspired by [this post](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/).
    88 changes: 88 additions & 0 deletions customerror.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,88 @@
    var util = require('util');

    function colorize (str, color) {
    var options = {
    red: '\u001b[31m'
    , green: '\u001b[32m'
    , yellow: '\u001b[33m'
    , blue: '\u001b[34m'
    , magenta: '\u001b[35m'
    , cyan: '\u001b[36m'
    , gray: '\u001b[90m'
    , reset: '\u001b[0m'
    };
    return options[color] + str + options.reset;
    };

    function pad (str, width) {
    return Array(width - str.length).join(' ') + str;
    };

    module.exports = CustomError;

    function CustomError (msg) {
    Error.call(this);

    // Write our opts to the object
    this.message = msg;
    this.name = 'CustomError';
    this.memory = process.memoryUsage();

    // We need the raw stack so we can make a JSON
    // object for writing to the logs.
    var orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack){ return stack; };
    Error.captureStackTrace(this, arguments.callee);
    this.__stack = this.stack;
    Error.prepareStackTrace = orig;

    // Lets make our JSON object.
    this._stack = [];
    for (var i = 0; i < this.__stack.length; i ++) {
    var frame = this.__stack[i];
    this._stack.push({
    filename: frame.getFileName()
    , typename: frame.getTypeName()
    , linenum: frame.getLineNumber()
    , funcname: frame.getFunctionName()
    , method: frame.getMethodName()
    });
    }

    // Since we provided our own prepareStackTrace, we need
    // to provide a new stack getter for display. Lets make
    // it look better while we are at it.
    Object.defineProperty(this, 'stack', {
    get: function () {
    var buf = [];

    buf.push('');
    buf.push(pad('', 8) + colorize(this.name, 'red'));
    buf.push(pad('', 8) + colorize(Array(this.name.length + 1).join('-'), 'gray'));
    buf.push(pad('', 8) + colorize(this.message, 'magenta'));
    buf.push(pad('', 8) + colorize((this.memory.heapTotal / 1048576).toFixed(3) + ' MB', 'blue') + colorize(' total ', 'gray'));
    buf.push(pad('', 8) + colorize((this.memory.heapUsed / 1048576).toFixed(3) + ' MB', 'blue') + colorize(' used ', 'gray'));
    buf.push(pad('', 8) + colorize(Array(this.name.length + 1).join('-'), 'gray'));
    buf.push('');

    this._stack.forEach(function (frame) {
    buf.push(' ' + colorize(pad(frame.linenum + '', 5), 'blue') + colorize(' ' + frame.filename, 'gray') );
    buf.push(pad('', 8) + colorize((frame.funcname ? frame.funcname : 'Anonymous'), 'green') + ' ' + colorize('[' + frame.typename + ']', 'yellow'));
    });

    buf.push('');
    return buf.join('\n');
    }
    });
    }

    util.inherits(CustomError, Error);

    CustomError.prototype.toJSON = function () {
    return {
    name: this.name
    , message: this.message
    , memory: this.memory
    , stack: this.stackJSON
    };
    }
    17 changes: 17 additions & 0 deletions testerror.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    var CustomError = require('./customerror');

    function log (err) {
    console.error(err);
    }

    function a (){
    b();
    }

    function b () {
    var err = new CustomError('There was a problem doing something in your app.');
    log(err.toJSON());
    throw err;
    }

    a();