Skip to content

Commit 61b1f47

Browse files
committed
Fix heading content to not include stack
fixes #10
1 parent 3cfb87a commit 61b1f47

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
unreleased
2+
==========
3+
4+
* Fix heading content to not include stack
5+
16
1.2.3 / 2014-11-21
27
==================
38

index.js

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ var util = require('util')
1919
* Module variables.
2020
*/
2121

22+
var doubleSpaceGlobalRegExp = / /g
2223
var inspect = util.inspect
24+
var newLineGlobalRegExp = /\n/g
2325
var toString = Object.prototype.toString
2426

2527
/**
@@ -85,17 +87,25 @@ exports = module.exports = function errorHandler(){
8587
if (e) return next(e);
8688
fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){
8789
if (e) return next(e);
88-
var stack = String(err.stack || '')
89-
.split('\n').slice(1)
90-
.map(function(v){ return '<li>' + escapeHtml(v).replace(/ /g, ' &nbsp;') + '</li>'; }).join('');
91-
html = html
92-
.replace('{style}', style)
93-
.replace('{stack}', stack)
94-
.replace('{title}', escapeHtml(exports.title))
95-
.replace('{statusCode}', res.statusCode)
96-
.replace(/\{error\}/g, escapeHtml(stringify(err)).replace(/ /g, ' &nbsp;').replace(/\n/g, '<br>'));
97-
res.setHeader('Content-Type', 'text/html; charset=utf-8');
98-
res.end(html);
90+
var str = stringify(err)
91+
var isInspect = !err.stack && String(err) === toString.call(err)
92+
var errorHtml = !isInspect
93+
? escapeHtmlBlock(str.split('\n', 1)[0] || 'Error')
94+
: 'Error'
95+
var stack = !isInspect
96+
? String(str).split('\n').slice(1)
97+
: [str]
98+
var stackHtml = stack
99+
.map(function (v) { return '<li>' + escapeHtmlBlock(v) + '</li>' })
100+
.join('')
101+
var body = html
102+
.replace('{style}', style)
103+
.replace('{stack}', stackHtml)
104+
.replace('{title}', escapeHtml(exports.title))
105+
.replace('{statusCode}', res.statusCode)
106+
.replace(/\{error\}/g, errorHtml)
107+
res.setHeader('Content-Type', 'text/html; charset=utf-8')
108+
res.end(body)
99109
});
100110
});
101111
// json
@@ -119,6 +129,17 @@ exports = module.exports = function errorHandler(){
119129

120130
exports.title = 'Connect';
121131

132+
/**
133+
* Escape a block of HTML, preserving whitespace.
134+
* @api private
135+
*/
136+
137+
function escapeHtmlBlock(str) {
138+
return escapeHtml(str)
139+
.replace(doubleSpaceGlobalRegExp, ' &nbsp;')
140+
.replace(newLineGlobalRegExp, '<br>')
141+
}
142+
122143
/**
123144
* Stringify a value.
124145
* @api private

test/test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ describe('errorHandler()', function () {
5858
.get('/')
5959
.set('Accept', 'text/html')
6060
.expect('Content-Type', /text\/html/)
61-
.expect(/<title>/)
62-
.expect(/Error: boom!/)
63-
.expect(/ &nbsp; &nbsp;at/)
61+
.expect(/<title>Error: boom!<\/title>/)
62+
.expect(/<h2><em>500<\/em> Error: boom!<\/h2>/)
63+
.expect(/<li> &nbsp; &nbsp;at/)
6464
.end(done)
6565
});
6666

0 commit comments

Comments
 (0)