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