]> git.cworth.org Git - obsolete/notmuch-web/blob - node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
Install the "express" node module via npm
[obsolete/notmuch-web] / node_modules / express / node_modules / connect / lib / middleware / errorHandler.js
1
2 /*!
3  * Connect - errorHandler
4  * Copyright(c) 2010 Sencha Inc.
5  * Copyright(c) 2011 TJ Holowaychuk
6  * MIT Licensed
7  */
8
9 /**
10  * Module dependencies.
11  */
12
13 var utils = require('../utils')
14   , url = require('url')
15   , fs = require('fs');
16
17 /**
18  * Flexible error handler, providing (_optional_) stack traces
19  * and error message responses for requests accepting text, html,
20  * or json.
21  *
22  * Options:
23  *
24  *   - `showStack`, `stack` respond with both the error message and stack trace. Defaults to `false`
25  *   - `showMessage`, `message`, respond with the exception message only. Defaults to `false`
26  *   - `dumpExceptions`, `dump`, dump exceptions to stderr (without terminating the process). Defaults to `false`
27  *
28  * Text:
29  *
30  *   By default, and when _text/plain_ is accepted a simple stack trace
31  *   or error message will be returned.
32  *
33  * JSON:
34  *
35  *   When _application/json_ is accepted, connect will respond with
36  *   an object in the form of `{ "error": error }`. 
37  *
38  * HTML:
39  *
40  *   When accepted connect will output a nice html stack trace.
41  *
42  * @param {Object} options
43  * @return {Function}
44  * @api public
45  */
46
47 exports = module.exports = function errorHandler(options){
48   options = options || {};
49
50   // defaults
51   var showStack = options.showStack || options.stack
52     , showMessage = options.showMessage || options.message
53     , dumpExceptions = options.dumpExceptions || options.dump
54     , formatUrl = options.formatUrl;
55
56   return function errorHandler(err, req, res, next){
57     res.statusCode = 500;
58     if (dumpExceptions) console.error(err.stack);
59     if (showStack) {
60       var accept = req.headers.accept || '';
61       // html
62       if (~accept.indexOf('html')) {
63         fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){
64           fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){
65             var stack = err.stack
66               .split('\n').slice(1)
67               .map(function(v){ return '<li>' + v + '</li>'; }).join('');
68               html = html
69                 .replace('{style}', style)
70                 .replace('{stack}', stack)
71                 .replace('{title}', exports.title)
72                 .replace(/\{error\}/g, utils.escape(err.toString()));
73               res.setHeader('Content-Type', 'text/html');
74               res.end(html);
75           });
76         });
77       // json
78       } else if (~accept.indexOf('json')) {
79         var json = JSON.stringify({ error: err });
80         res.setHeader('Content-Type', 'application/json');
81         res.end(json);
82       // plain text
83       } else {
84         res.writeHead(500, { 'Content-Type': 'text/plain' });
85         res.end(err.stack);
86       }
87     } else {
88       var body = showMessage
89         ? err.toString()
90         : 'Internal Server Error';
91       res.setHeader('Content-Type', 'text/plain');
92       res.end(body);
93     }
94   };
95 };
96
97 /**
98  * Template title.
99  */
100
101 exports.title = 'Connect';