-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for headers in errors #668
Conversation
// for example: the keys are always stored in lowercase | ||
var errHeaders = err.headers ? Object.keys(err.headers) : []; | ||
var newHeaders = {}; | ||
for (var i = 0; i < errHeaders.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wish we didn't have to support node < 4. then we could do for-of. sigh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (var key in err.headers)
is ok and have the similar performance with a small number of key.
for in x 2,743,592 ops/sec ±1.06% (90 runs sampled)
Object.keys x 3,294,202 ops/sec ±1.36% (91 runs sampled)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides, for-of is too slow at the moment
yeah, hmmm... we need a doc just on error handling |
looks good to me. people who would find interest in this, would you like to review? @niftylettuce @menems @dead-horse @tejasmanohar @cesarandreu @pensierinmusica @felixfbecker @ruimarinho @fixe |
this.res._headers = {}; | ||
var newHeaderKeys = Object.keys(newHeaders); | ||
for (var i = 0; i < newHeaderKeys.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.set(newHeaders);
hi , I think the ability to add new header on error is a good point , but i am not totally agree about keeping already set header in that way. May be In addition we can have a global var like As I said, the problem with that approach is, the module responsible of keeping header have to know which headers are already set. (it's not always the case) and the goal is remove some boilerplate i think . But I can't judge that because i haven't make a pull request for that issue (missing time sorry) |
@menems Yeah this is a bit hacky. Maybe have Edit: I understand your point now. Yeah I can see that being a problem. However, instead of a |
6fdb4f2
to
9f94392
Compare
I'd rather remove keep header hack like Keep this feature simple and obvious. |
@dead-horse Sounds good. I'll implement that in a bit. Would you like something to solve menems' problem, that the error thrower might not know which headers to keep? I think that a |
I also think that a |
9f94392
to
7977eb7
Compare
not really sure how much should we do in the default error handler, because lots of people already use third party error handlers that don't implement like this may cause some unexpected behavior. so we'd better keep the rules clearly enough and make third party error handlers follow these rules.
|
@dead-horse my use case, and i think it 's a standard one. I have a cors middleware and an authentication behavior, if i use My only solution is to catch the error and set status to bypass the context.onerror.
It's a little annoying i think because status will be set by default ctx.onerror handler. |
@menems the default error handler already sets the status: https://github.com/koajs/koa/blob/master/lib/context.js#L135 |
@PlasmaPower Yes I know but it remove headers too https://github.com/koajs/koa/blob/master/lib/context.js#L121 |
@menems Oh, I thought that you were then throwing the error again after setting the status. Speaking of that, that might actually eliminate the use case for app.use(function*(next){
try {
yield next;
} catch (err) {
err.headers = err.headers || {};
err.headers['x-my-header'] = this.response.get('x-my-header');
throw err;
}
}) |
We seem to have a wiki page on error handling, should I make an edit there once this merges to document this? I'm not quite sure on why we have koajs.com, the github wiki, and |
koajs.com is built from the docs. we should put it in the docs! |
hahaha good call |
@jonathanong Oh, I see. I thought they weren't the same since a recent change wasn't in there. I'll add a docs page for error handling then. |
7977eb7
to
36119c2
Compare
I've added documentation for this. Is there anything else that needs to be done? |
@PlasmaPower : ok so if I understand the goal of this pr is to pass header on error and throw it again?
ps: I'm still thinking this middleware should be unnecessary with a global var that keep headers for status != 5XX |
@menems this is more aimed at koa libraries I think. They shouldn't implement their own error handlers. In your case, you should probably just make an |
@PlasmaPower : nop, i tried that before but you can override effectively |
I see. Yeah since app.on(async (ctx, next) => {
try {
await next();
} catch (err) {
err.status = err.status || 500;
ctx.body = 'An error occured: ' + err.status;
ctx.status = err.status;
}
}) |
If you do that, aren't you deoptimizing the code? |
@thelinuxlich What do you mean? |
try/catch deoptimizes V8 code |
@thelinuxlich I wasn't aware of that. However, doing a bit of research, it would appear that it will not apply to the contents of the next call, so the impact is minimal. Is this the case? Also, if try-catch is to be avoided, you can always just do app.on((ctx, next) => {
return next().catch(function(err){
err.status = err.status || 500;
ctx.body = 'An error occured: ' + err.status;
ctx.status = err.status;
})
}) |
|
hmmm interesting |
tried to see if removing the try/catch was faster... it was not. koajs/compose#49 |
i believe it only deoptimizes that function, anyway |
I propose adding 5 more try-catches for optimal performance /s |
+1 on more try/catches. Maybe add a finally block aswell? |
anyways, this LGTM |
I need to fix the docs before merging, it should be done soon. I was a bit confused on |
36119c2
to
f2d826a
Compare
Okay they should be good now. |
LGTM |
f2d826a
to
aed6278
Compare
Small change to reflect current implementation: |
Resolves #571. I'd like to document this, but I'm not quite sure where.