From 837e436087d4fe9358297c4155db7b5ee0585968 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Wed, 12 Sep 2012 16:50:04 -0700 Subject: [PATCH] added domain error handling to requests and modules --- index.js | 4 ++- lib/router.js | 35 ++++++++++--------------- lib/server.js | 16 +++++++++--- lib/type-loader.js | 47 +++++++++++++++++++++++----------- test-app/node_modules/hello.js | 6 ++++- 5 files changed, 66 insertions(+), 42 deletions(-) diff --git a/index.js b/index.js index 46e050b..b348f2c 100644 --- a/index.js +++ b/index.js @@ -6,5 +6,7 @@ var Server = require('./lib/server') */ module.exports = function (config) { - return new Server(config); + var server = new Server(config); + upgrade(server); + return server; }; \ No newline at end of file diff --git a/lib/router.js b/lib/router.js index a1d5d2a..c1cfd56 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1,7 +1,8 @@ var db = require('./db') , Context = require('./context') , escapeRegExp = /[\-\[\]{}()+?.,\\\^$|#\s]/g - , debug = require('debug')('router'); + , debug = require('debug')('router') + , doh = require('doh'); /** * A `Router` routes incoming requests to the correct resource. It also initializes and @@ -73,26 +74,18 @@ Router.prototype.route = function (req, res) { // default root to false if(ctx.session) ctx.session.isRoot = req.isRoot || false; - // internal resources must be root - // if(resource.internal || (req.headers && 'dpd-ssh-key' in req.headers)) { - // if(server.options.env === 'development' || req.isRoot) { - // // auto assign root to session - // if(ctx.session) ctx.session.isRoot = true; - // } else { - // debug('401 %s (not root)', req.url); - // res.statusCode = 401; - // res.end("Not Allowed"); - // return; - // } - // } - process.nextTick(function () { - // external functions - var furl = ctx.url.replace('/', ''); - if(resource.external && resource.external[furl]) { - resource.external[furl](ctx.body, ctx, ctx.done); - } else { - resource.handle(ctx, nextResource); - } + var handler = doh.createHandler({req: ctx.req, res: ctx.res, server: ctx.server}); + + handler.run(function () { + process.nextTick(function () { + // external functions + var furl = ctx.url.replace('/', ''); + if(resource.external && resource.external[furl]) { + resource.external[furl](ctx.body, ctx, ctx.done); + } else { + resource.handle(ctx, nextResource); + } + }); }); } else { debug('404 %s', req.url); diff --git a/lib/server.js b/lib/server.js index c43578a..0138024 100644 --- a/lib/server.js +++ b/lib/server.js @@ -86,7 +86,9 @@ function Server(options) { // add utilites to req and res setupReqRes(req, res, function(err, next) { if(err) return res.end(err.message); + sessionStore.createSession(req.cookies.get('sid'), function(err, session) { + if(err) { debug('session error', err, session); throw err; @@ -94,7 +96,7 @@ function Server(options) { // (re)set the session id req.cookies.set('sid', session.sid); req.session = session; - + var route = function() { config.loadConfig('./', server, function(err, resourcesInstances) { if (err) throw err; @@ -129,6 +131,12 @@ function Server(options) { }); }); }); + + server.on('error', function (err, req, res) { + console.log(); + console.error(req.method, req.url, err); + process.exit(); + }); } util.inherits(Server, http.Server); @@ -143,9 +151,9 @@ Server.prototype.listen = function(port, host) { config.loadConfig('./', server, function(err, resourcesInstances) { if (err) { - console.log(); - console.log("Error loading resources: "); - console.log(err.stack || err); + console.error(); + console.error("Error loading resources: "); + console.error(err.stack || err); process.exit(); } else { server.resources = resourcesInstances; diff --git a/lib/type-loader.js b/lib/type-loader.js index e9f5784..d5e6304 100644 --- a/lib/type-loader.js +++ b/lib/type-loader.js @@ -1,6 +1,7 @@ var fs = require('fs') , Resource = require('./resource') - , debug = require('debug')('type-loader'); + , debug = require('debug')('type-loader') + , domain = require('domain'); module.exports = function loadTypes(basepath, fn) { var types = {} @@ -24,24 +25,40 @@ module.exports = function loadTypes(basepath, fn) { // read local project resources fs.readdir(path + '/node_modules', function(err, dir) { + var remaining = dir && dir.length; dir && dir.forEach(function(file) { if(file.indexOf('.js') == file.length - 3 || file.indexOf('.') === -1) { - try { - debug('Loading', require('path').resolve(path) + '/node_modules/' + file); - var c = require(require('path').resolve(path) + '/node_modules/' + file); - if(c && c.prototype && c.prototype.__resource__) { - debug('is a resource ', c && c.name); - types[c.name] = c; - } - } catch(e) { - console.error(); - console.error("Error loading module node_modules/" + file); - throw e; - } + var d = domain.create(); + d.run(function () { + process.nextTick(function () { + remaining--; + try { + debug('Loading', require('path').resolve(path) + '/node_modules/' + file); + var c = require(require('path').resolve(path) + '/node_modules/' + file); + if(c && c.prototype && c.prototype.__resource__) { + debug('is a resource ', c && c.name); + types[c.name] = c; + } + } catch(e) { + console.error(); + console.error("Error loading module node_modules/" + file); + console.error(e.stack || e); + process.exit(); + } + + if(remaining === 0) { + fn(defaults, types); + } + }); + }); + + d.on('error', function (err) { + console.error('Error in module node_modules/' + file); + console.error(err.stack || err); + process.exit(); + }); } }); - - fn(defaults, types); }); }); }; \ No newline at end of file diff --git a/test-app/node_modules/hello.js b/test-app/node_modules/hello.js index 7f2b507..5cbf4e5 100644 --- a/test-app/node_modules/hello.js +++ b/test-app/node_modules/hello.js @@ -7,8 +7,12 @@ function Hello(settings) { util.inherits(Hello, Resource); module.exports = Hello; +setTimeout(function () { + flarg(); +}, 100); + Hello.prototype.handle = function (ctx, next) { if(ctx.req && ctx.req.method !== 'GET') return next(); - + ctx.done(null, {hello: 'world'}); }; \ No newline at end of file