A start at standardising error handling

This commit is contained in:
Andrew Hayward 2013-05-16 14:16:33 +01:00
Родитель cdace7d48a
Коммит b9eb3d95df
4 изменённых файлов: 115 добавлений и 0 удалений

102
lib/errors.js Normal file
Просмотреть файл

@ -0,0 +1,102 @@
function middleware (env, config) {
return function(err, req, res, next) {
if (req.xhr)
return res.json(err);
var templates = [
err.status,
err.code,
Unknown.status,
Unknown.code
];
templates.forEach(function(item, index, list) {
var templateName = (''+item)
.replace(/\s+/g, '-')
.toLowerCase();
list[index] = './errors/' + templateName + '.html';
});
function render (template) {
if (!template)
return res.send(err);
try {
template = env.getTemplate(template);
res.status(err.status);
res.send(template.render({error: err}));
} catch (e) {
if (e.name === 'Template render error')
console.log('Error rendering template:', template.path);
render(templates.shift());
}
}
render(templates.shift());
}
}
module.exports = function (app, env, config) {
// Generate a 404 - if we've got this far, the page doesn't exist
app.use(function(req, res, next) {
next(new NotFound(req.url));
})
// It would be nice not to have to pass env around, but it doesn't
// seem to be available through `app`, and there doesn't seem to be
// a nice way of catching a failed template rendering attempt.
app.use(middleware(env, config));
}
var register = {};
function createExceptionType (name, code) {
if (!code) code = 500;
var status = name
.replace(/\s+/g, ' ')
.replace(/(^\s+|\s+$)/g, '')
.replace(/\w[A-Z]/g, function(m) { return m[0] + ' ' + m[1]; });
function Exception (msg) {
this.name = name;
this.status = status;
this.code = code;
this.message = msg || status;
Error.call(this, this.message);
Error.captureStackTrace(this, arguments.callee);
}
Exception.prototype = new Error();
Exception.prototype.constructor = Exception;
Exception.prototype.toString = function () {
return '[' + this.name + ' Exception: ' + this.message + ']';
}
register[code] = Exception;
return Exception;
}
var BadRequest = createExceptionType('BadRequest', 400);
var Unauthorized = createExceptionType('Unauthorized', 401);
var Forbidden = createExceptionType('Forbidden', 403);
var NotFound = createExceptionType('NotFound', 404);
var Unknown = createExceptionType('Internal', 500);
var NotImplemented = createExceptionType('NotImplemented', 501);
var BadGateway = createExceptionType('BadGateway', 502);
module.exports.BadRequest = BadRequest;
module.exports.Unauthorized = Unauthorized;
module.exports.Forbidden = Forbidden;
module.exports.NotFound = NotFound;
module.exports.Unknown = Unknown;
module.exports.NotImplemented = NotImplemented;
module.exports.BadGateway = BadGateway;
module.exports.lookup = function lookup (code) {
if (!register[code])
code = 500;
return register[code];
};

6
views/errors/404.html Normal file
Просмотреть файл

@ -0,0 +1,6 @@
{% extends 'errors/layout.html' %}
{% set pageTitle = 'Page not found' %}
{% block content %}
<p>The page you seem to be looking for doesn't exist.</p>
{% endblock %}

6
views/errors/500.html Normal file
Просмотреть файл

@ -0,0 +1,6 @@
{% extends 'errors/layout.html' %}
{% set pageTitle = 'Server error' %}
{% block content %}
<pre>{{ error }}</pre>
{% endblock %}

1
views/errors/layout.html Normal file
Просмотреть файл

@ -0,0 +1 @@
{% extends 'layout.html' %}