Slide 1

Slide 1 text

JS Error Handling JS Error Handling

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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'); } }

Slide 4

Slide 4 text

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.

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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.

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Extending Error Extending Error Your own Error Objects Your own Error Objects

Slide 9

Slide 9 text

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']

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Errors in Node.js Errors in Node.js

Slide 14

Slide 14 text

"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);

Slide 15

Slide 15 text

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; } // ... // }); };

Slide 16

Slide 16 text

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); } }

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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); };

Slide 20

Slide 20 text

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);

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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