Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Error Handling in Javascript and Node.js

Error Handling in Javascript and Node.js

Todays Menu:
1. Error Object Definition
2. Error Best Practices
3. Extending the Error Object
4. Practical uses in Node.js
5. Using Errors at your API

Thanos Polychronakis

January 21, 2016
Tweet

More Decks by Thanos Polychronakis

Other Decks in Technology

Transcript

  1. JS Error Handling
    JS Error Handling

    View full-size slide

  2. Todays Menu
    Todays Menu
    1. Error Object Definition
    2. Error Best Practices
    3. Extending the Error Object
    4. Practical uses in Node.js
    5. Using Errors at your API

    View full-size slide

  3. The Error Constructor
    The Error Constructor
    new Error([message[, fileName[, lineNumber]]])
    function equals(a, b) {
    if (a !== b) {
    throw new Error('Values are not equal');
    }
    }

    View full-size slide

  4. Error Properties
    Error Properties
    Standard
    Standard
    message The error message.
    name The error name.
    Mozilla
    Mozilla (node.js)
    (node.js)
    fileName Path to file that raised the error.
    lineNumber The line number in the file that raised
    the error.
    columnNumber The col number.
    stack The error execution stack.

    View full-size slide

  5. Error Methods
    Error Methods
    toString() Returns a string representing the Error
    Object, overrides the Object.prototype.toString()
    method.

    View full-size slide

  6. Error Types
    Error Types
    EvalError Creates an instance representing an error that occurs regarding
    the global function eval().
    InternalError Creates an instance representing an error that occurs when
    an internal error in the JavaScript engine is thrown. E.g. "too much recursion".
    RangeError Creates an instance representing an error that occurs when a
    numeric variable or parameter is outside of its valid range.
    ReferenceError Creates an instance representing an error that occurs
    when de-referencing an invalid reference.
    SyntaxError Creates an instance representing a syntax error that occurs
    while parsing code in eval().
    TypeError Creates an instance representing an error that occurs when a
    variable or parameter is not of a valid type.
    URIError Creates an instance representing an error that occurs when
    encodeURI() or decodeURI() are passed invalid parameters.

    View full-size slide

  7. Javascript Error Best Practises
    Javascript Error Best Practises
    General Advice
    Always be using Error Objects
    More Specifically
    In your [node.js] callbacks
    In error events you emit
    In your API (normalize)
    Throw in your Promises

    View full-size slide

  8. Extending Error
    Extending Error
    Your own Error Objects
    Your own Error Objects

    View full-size slide

  9. Classical Inheritance?
    Classical Inheritance?
    var util = require('util');
    var CustomError = function() {
    Error.apply(this, arguments);
    this.customProp = true;
    };
    util.inherits(CustomError, Error);
    console.log(customError.message); // undefined
    console.log(customError.stack); // empty response
    console.log(customError instanceof Error); // true
    console.log(Object.keys(customError)); // ['customProp']

    View full-size slide

  10. What happened here?
    What happened here?
    var util = require('util');
    var CustomError = function() {
    Error.apply(this, arguments);
    this.customProp = true;
    };
    util.inherits(CustomError, Error);
    Error is a function that returns a new Error object and does
    not manipulate this in any way

    View full-size slide

  11. How to extend Error
    How to extend Error (node.js)
    (node.js)
    var util = require('util');
    var CustomError = function(message) {
    Error.captureStackTrace(this, this.constructor);
    this.name = 'CustomError';
    this.message = message;
    };
    util.inherits(CustomError, Error);
    instanceof Error works
    Stack traces work as expected
    Can extend itself
    captureStackTrace() is v8 specific
    For web replace with local throw

    View full-size slide

  12. How to extend Error
    How to extend Error (web)
    (web)
    var util = require('util');
    var CustomError = function(message) {
    // Use V8's native method if available, otherwise fallback
    if ('captureStackTrace' in Error) {
    Error.captureStackTrace(this, CustomError);
    } else {
    this.stack = (new Error()).stack;
    }
    this.name = 'CustomError';
    this.message = message;
    };
    util.inherits(CustomError, Error);
    instanceof Error works
    Stack traces have actual file on second line
    Can extend itself

    View full-size slide

  13. Errors in Node.js
    Errors in Node.js

    View full-size slide

  14. "Signing" Errors
    "Signing" Errors
    Errors in Node.js
    errors.DatabaseError = function(message) {
    Error.captureStackTrace(this, this.constructor);
    this.name = 'AcmeDatabaseError';
    this.message = message;
    // custom props
    this.error = true;
    };
    util.inherits(errors.DatabaseError, Error);

    View full-size slide

  15. Augmented Errors
    Augmented Errors
    Errors in Node.js
    var appError = require('app-errors');
    // ... //
    User.prototype.hasPrivilege = function(userId, privilege, cb) {
    this.fetchUser(userId, function(err, udo) {
    if (!udo) {
    var err = new appError.EmptyResultsError('User not found');
    err.userId = userId;
    cb(err);
    return;
    }
    // ... //
    });
    };

    View full-size slide

  16. Catch Specific Errors
    Catch Specific Errors
    Errors in Node.js
    try {
    myroutine(); // may throw three types of exceptions
    } catch (ex) {
    if (ex instanceof TypeError) {
    } else if (ex instanceof RangeError) {
    } else if (ex instanceof EvalError) {
    } else {
    logMyErrors(ex);
    }
    }

    View full-size slide

  17. Using Errors on API
    Using Errors on API
    how to work with express
    how to work with express

    View full-size slide

  18. The Overview
    The Overview
    Using Errors on API
    Create custom Errors with an httpCode or similar
    attribute, set to 500 by default.
    Throw them or augment existing Error objects by
    defining the httpCode.
    Create an express error middleware handling those
    errors.
    Pipe all error handling to next

    View full-size slide

  19. Pipe Errors to next
    Pipe Errors to next
    Using Errors on API
    UserCtrl.prototype.fetchUser = function(req, res, next) {
    this.userEnt.readOne(req.param.userId)
    .then(res.json)
    .catch(next);
    };

    View full-size slide

  20. Express Error Handler
    Express Error Handler
    Using Errors on API
    var customErrorHandler = function (err, req, res, next) {
    var httpCode = 500;
    httpCode = err.httpCode || httpCode;
    res.status(httpCode);
    // figure out what the client accepts
    if (helpers.isRequestJson(req)) {
    res.json(error);
    } else {
    res.render('error/' + error.httpCode, {error: error});
    }
    };
    // Express error handler must always be last
    // in all of your middleware
    app.use(customErrorHandler);

    View full-size slide

  21. Thank you
    Thanasis Polychronakis
    @thanpolas
    https://speakerdeck.com/thanpolas

    View full-size slide

  22. Questions?
    Thanasis Polychronakis
    @thanpolas
    https://speakerdeck.com/thanpolas

    View full-size slide