added domain error handling to module loading, fixed 404 tests with faux router req and res objects

This commit is contained in:
Ritchie Martori
2012-09-17 14:08:43 -07:00
parent ce36a13759
commit 654428ce8d
5 changed files with 95 additions and 47 deletions

View File

@@ -7,7 +7,8 @@ var fs = require('fs')
, ClientLib = require('./resources/client-lib')
, Dashboard = require('./resources/dashboard')
, debug = require('debug')('config-loader')
, ignore = {};
, ignore = {}
, domain = require('domain');
/*!
* Loads resources from a project folder
@@ -88,29 +89,38 @@ module.exports.loadConfig = function(basepath, server, fn) {
if (types[type]) {
try {
resource = new types[o.config.type](name, o);
if (resource.load) {
remaining++;
resource.load(function(err) {
remaining--;
if (err) {
error = err;
return done();
}
var d = domain.create();
d.on('error', function (err) {
err.message += ' - when initializing: ' + o.config.type;
console.error(err.stack || err);
process.exit();
});
remaining++;
d.run(function () {
process.nextTick(function () {
remaining--;
resource = new types[o.config.type](name, o);
if (resource.load) {
remaining++;
resource.load(function(err) {
remaining--;
if (err) {
error = err;
return done();
}
resources.push(resource);
done();
});
} else {
resources.push(resource);
done();
});
} else {
resources.push(resource);
}
} catch(e) {
error = e;
error.message += ' - when initializing: ' + o.config.type;
}
}
});
});
} else {
error = 'cannot find type ' + o.config.type + ' for resource ' + name;
}
if(error) throw error;
}
function loadResources(types) {
@@ -121,7 +131,7 @@ module.exports.loadConfig = function(basepath, server, fn) {
remaining++;
fs.stat(path.join(basepath, 'resources', file), function (err, stat) {
remaining--;
error = err;
if(err) throw err;
if(stat && stat.isDirectory()) {
var spath = path.join(basepath, 'resources', file, 'config.json')
, resource = file;
@@ -132,15 +142,14 @@ module.exports.loadConfig = function(basepath, server, fn) {
fs.readFile(spath, 'utf-8', function(err, data) {
remaining--;
var settings;
if(err) error = err;
if(err) throw err;
try {
settings = JSON.parse(data);
loadResource(file, path.join(basepath, 'resources', file), settings, types);
} catch(e) {
error = e;
return fn(error);
if(err) throw err;
}
done();

View File

@@ -86,9 +86,8 @@ Router.prototype.route = function (req, res) {
}
} else {
debug('404 %s', req.url);
console.log('...');
res.statusCode = 404;
throw new Error('Resource not found');
res.domain.emit('error', new Error('Resource not found'));
}
});
});

View File

@@ -132,9 +132,9 @@ function Server(options) {
});
});
server.on('error', function (err, req, res) {
server.on('request:error', function (err, req, res) {
console.log();
console.error(req.method, req.url, err);
console.error(req.method, req.url, err.stack || err);
process.exit();
});
}
@@ -150,7 +150,7 @@ Server.prototype.listen = function(port, host) {
var server = this;
config.loadConfig('./', server, function(err, resourcesInstances) {
if (err) {
if (err) {
console.error();
console.error("Error loading resources: ");
console.error(err.stack || err);
@@ -159,7 +159,6 @@ Server.prototype.listen = function(port, host) {
server.resources = resourcesInstances;
http.Server.prototype.listen.call(server, port || server.options.port, host || server.options.host);
}
});
return this;
};

View File

@@ -1,6 +1,35 @@
var Router = require('../lib/router')
, Resource = require('../lib/resource');
function fauxReq(url) {
var fn = function (){};
return {
url: url,
headers: {},
resume: fn,
on: fn,
emit: fn
};
}
function fauxRes() {
var fn = function (){};
return {
headers: {},
resume: fn,
on: fn,
emit: fn,
setHeader: fn,
end: fn
};
}
function fauxServer() {
return {
emit: function () {}
}
}
describe('Router', function() {
describe('.route()', function() {
@@ -20,7 +49,7 @@ describe('Router', function() {
it('should route to an exactly matching resource', function(done) {
var resource = new Resource('foo')
, other = new Resource('')
, router = new Router([resource, other], {});
, router = new Router([resource, other], fauxServer());
this.timeout(100);
@@ -38,7 +67,7 @@ describe('Router', function() {
it ('should route to resources in turn', function(done) {
var foobar = new Resource('foo/bar')
, foo = new Resource('foo')
, router = new Router([foo, foobar], {})
, router = new Router([foo, foobar], fauxServer())
, foobarCalled = false;
this.timeout(100);
@@ -57,25 +86,29 @@ describe('Router', function() {
it ('should return 404 if no resources match', function(done) {
var foo = new Resource('foo')
, router = new Router([foo], {});
, router = new Router([foo], fauxServer());
this.timeout(100);
var req = fauxReq('/dont-match')
, res = fauxRes();
res.end = function () {
if(res.statusCode != 404) throw new Error('incorrect status for resource not found');
done();
}
foo.handle = function() {
throw "/foo was handled";
};
router.route({url: '/dont-match'}, {end: function() {
expect(this.statusCode).to.equal(404);
done();
}});
router.route(req, res);
});
it ('should return 404 if all resources call next', function(done) {
var foobar = new Resource('foo/bar')
, foo = new Resource('foo')
, router = new Router([foo, foobar], {});
, router = new Router([foo, foobar], fauxServer());
this.timeout(100);
@@ -86,16 +119,21 @@ describe('Router', function() {
foo.handle = function(ctx, next) {
next();
};
router.route({url: '/foo/bar'}, {end: function() {
expect(this.statusCode).to.equal(404);
var req = fauxReq('/dont-match')
, res = fauxRes();
res.end = function () {
if(res.statusCode != 404) throw new Error('incorrect status for resource not found');
done();
}});
}
router.route(req, res);
});
it('should modify ctx.url to remove the base path', function(done) {
var foo = new Resource('foo')
, router = new Router([foo], {});
, router = new Router([foo], fauxServer());
this.timeout(1000);
@@ -103,8 +141,11 @@ describe('Router', function() {
expect(ctx.url).to.equal('/1234');
done();
};
router.route({url: '/foo/1234'}, {});
var req = fauxReq('/foo/1234')
, res = fauxRes();
router.route(req, res);
});
it('should still have a leading slash for root resources', function(done) {

File diff suppressed because one or more lines are too long