Skip to content

Commit 6fdb4f2

Browse files
committed
Add support for headers in errors
1 parent 93c356a commit 6fdb4f2

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

lib/context.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,26 @@ var proto = module.exports = {
117117
return;
118118
}
119119

120-
// unset all headers
120+
// unset all headers not explicitly kept
121+
// while it's inconvenient to use setHeader and getHeader,
122+
// res._headers isn't documentented and can't be relied on much
123+
// for example: the keys are always stored in lowercase
124+
var errHeaders = err.headers ? Object.keys(err.headers) : [];
125+
var newHeaders = {};
126+
for (var i = 0; i < errHeaders.length; i++) {
127+
var header = errHeaders[i];
128+
if (err.headers[header] === true) { // keep the header
129+
newHeaders[header] = this.res.getHeader(header);
130+
} else {
131+
newHeaders[header] = err.headers[header];
132+
}
133+
}
121134
this.res._headers = {};
135+
var newHeaderKeys = Object.keys(newHeaders);
136+
for (var i = 0; i < newHeaderKeys.length; i++) {
137+
var key = newHeaderKeys[i];
138+
this.res.setHeader(key, newHeaders[key]);
139+
}
122140

123141
// force text/plain
124142
this.type = 'text';

test/context/onerror.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,43 @@ describe('ctx.onerror(err)', function(){
5252
})
5353
})
5454

55+
it('should keep headers specified in the error', function(done){
56+
var app = koa();
57+
58+
app.use(function *(next){
59+
this.set('Vary', 'Accept-Encoding');
60+
this.set('X-CSRF-Token', 'asdf');
61+
this.set('X-Example-Kept', 'should be kept');
62+
this.body = 'response';
63+
64+
throw Object.assign(new Error('boom'), {
65+
status: 418,
66+
expose: true,
67+
headers: {
68+
'X-Example-Kept': true,
69+
'X-New-Header': 'Value'
70+
}
71+
})
72+
})
73+
74+
var server = app.listen();
75+
76+
request(server)
77+
.get('/')
78+
.expect(418)
79+
.expect('Content-Type', 'text/plain; charset=utf-8')
80+
.expect('X-Example-Kept', 'should be kept')
81+
.expect('X-New-Header', 'Value')
82+
.end(function(err, res){
83+
if (err) return done(err);
84+
85+
res.headers.should.not.have.property('vary');
86+
res.headers.should.not.have.property('x-csrf-token');
87+
88+
done();
89+
})
90+
})
91+
5592
describe('when invalid err.status', function(){
5693
describe('not number', function(){
5794
it('should respond 500', function(done){

0 commit comments

Comments
 (0)