Hi, In an asynchronous environment like node.js, can it be hard to handle errors, specially by the asynchronous nature of node.js. Exceptions is good for synchronous programming, but does not fit well into a more complex asynchronous environment. I have come up with a solution, and want your thoughts about it.
var error = require('error'), //my module context = error.context, errc = error.errc, severity = error.severity; //Create a sink, a place there all log message will go to. context.add.sink('console', { on_message: function (err) { //replace this with your favourite logging library console.log("Error in context " + err.context.name() + ": " + err.message); }, severity: [0, 1, 2, 3, 4, 5, 6, 7, 8] }); context.add.errorListener(Error, function (err, next) { //invoked only if the following statement is true: (err instanceof Error), therefore is polymorphism possible. err.log(); //call all sinks next(); //call next errorListener, if any }); context.run(function () { require('fs').readFile(__filename, this.intercept(function(file) { //no error, lets throw one throw new Error("My custom error"); //will be caught, by by context. Will not crash the application. })); var makeError = true; require('http').createServer(function (request, response) { var httpContext = context.newContext('httpContext'); httpContext.add.errorListener(errc.httpError, function (err, next) { //a errc.httpError was emitted. Lets display a error page for the user. response.writeHead(err.code, { 'Content-Type': 'text/plain' }); response.end(err.message); next(); }); httpContext.run(function () { if (makeError= !makeError) { //every two throw new errc.httpError(); } response.writeHead(200, { 'Content-Type': 'text/plain' }); response.end('Hello World\n'); }); }).listen(8080); }); //errc.httpError implementation. The method utility.extend will only make sure the object has some properties. var http = require('http'), util = require('util'), utility = require('utility'); //base error for all errors. function error(params) { utility.extend(this, { message: "Error" }); Error.call(this, params.message); Error.captureStackTrace(this, this.constructor); } util.inherits(error, Error); function httpError(params) { params = utility.extend(params, { code: 500 }); utility.extend(params, { message: params.code + " " + http.STATUS_CODES[params.code] }); utility.extend(this, params); error.call(this, params); } util.inherits(httpError, error); var api = { error: error, httpError: httpError }; module.exports = api; //severity implementation: var api = { emergency: 0, alert: 1, critical: 2, error: 3, warning: 4, notice: 5, info: 6, debug: 7, trace: 8 }; module.exports = api; OUTPUT: Error in context Application: My custom error Error in context Application.httpContext: 500 Internal Server Error (after you have visit localhost:8080 two times) Application is the default name of the top context, therefore "Application.httpContext". Everything connected to a context will only exist in it and all its sub-contexts, so any errorListener/sink which are added to httpContext will be invisible from all contexts above itself. Some variables is dynamically added to all errors as well, like a log method and the current context. I see the following advantages: - Greater error control together with nested error handlers, there polymorphism can be used, as in the example. - Scope based. Every error-listener/sink is bound to the current context there it is created and all sub context. - Simple to create new errors (see how httpError is created above) and severities. and the following disadvantages: - All code which may thrown must be wrapped within context.run or context.intercept. - The performance may decrease a little. It depends on the reason that all errors must be routed up to the top context if none error listener ignore calling next(). All log message will also be written to all sinks up to the top context. However it should be a CPU bound task, so it should never be noticeable. Thoughts? Any comment is grateful :-) Thanks in advance! -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en