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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en