rc@73: /*! rc@73: * errorhandler rc@73: * Copyright(c) 2010 Sencha Inc. rc@73: * Copyright(c) 2011 TJ Holowaychuk rc@73: * MIT Licensed rc@73: */ rc@73: rc@73: /** rc@73: * Module dependencies. rc@73: */ rc@73: rc@73: var accepts = require('accepts') rc@73: var escapeHtml = require('escape-html'); rc@73: var fs = require('fs'); rc@73: rc@73: /** rc@73: * Error handler: rc@73: * rc@73: * Development error handler, providing stack traces rc@73: * and error message responses for requests accepting text, html, rc@73: * or json. rc@73: * rc@73: * Text: rc@73: * rc@73: * By default, and when _text/plain_ is accepted a simple stack trace rc@73: * or error message will be returned. rc@73: * rc@73: * JSON: rc@73: * rc@73: * When _application/json_ is accepted, connect will respond with rc@73: * an object in the form of `{ "error": error }`. rc@73: * rc@73: * HTML: rc@73: * rc@73: * When accepted connect will output a nice html stack trace. rc@73: * rc@73: * @return {Function} rc@73: * @api public rc@73: */ rc@73: rc@73: exports = module.exports = function errorHandler(){ rc@73: // get environment rc@73: var env = process.env.NODE_ENV || 'development' rc@73: rc@73: return function errorHandler(err, req, res, next){ rc@73: // respect err.status rc@73: if (err.status) { rc@73: res.statusCode = err.status rc@73: } rc@73: rc@73: // default status code to 500 rc@73: if (res.statusCode < 400) { rc@73: res.statusCode = 500 rc@73: } rc@73: rc@73: // write error to console rc@73: if (env !== 'test') { rc@73: console.error(err.stack || String(err)) rc@73: } rc@73: rc@73: // cannot actually respond rc@73: if (res._header) { rc@73: return req.socket.destroy() rc@73: } rc@73: rc@73: // negotiate rc@73: var accept = accepts(req) rc@73: var type = accept.types('html', 'json', 'text') rc@73: rc@73: // Security header for content sniffing rc@73: res.setHeader('X-Content-Type-Options', 'nosniff') rc@73: rc@73: // html rc@73: if (type === 'html') { rc@73: fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){ rc@73: if (e) return next(e); rc@73: fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){ rc@73: if (e) return next(e); rc@73: var stack = (err.stack || '') rc@73: .split('\n').slice(1) rc@73: .map(function(v){ return '