koa: ctx.throw() kills the server
This server
const app = new (require('koa'))()
// first middleware
app.use(async (ctx, next) => {
next()
})
// second middleware
app.use(async ctx => {
ctx.throw(400)
})
app.listen(3000)
process.on('unhandledRejection', reason => {
throw reason
})
will blowup when request will get to the second middleware, and you will see it in the error
BadRequestError: Bad Request
at Object.throw (...\node_modules\koa\lib\context.js:91:23)
at .../server.js:10:3
at Generator.next (<anonymous>)
at step (...\server.js:3:191)
at ...\server.js:3:437
at ...\server.js:3:99
at app.use (.../server.js:9:1)
at dispatch (...\node_modules\koa-compose\index.js:44:32)
at next (...\node_modules\koa-compose\index.js:45:18)
at .../server.js:6:3
Error message blames request but the real problem is in the first middleware, where next() doesn’t have await before it. Lack of await is probably a bug. The issue points are:
- Should it blowup the server?
- Every thing would be ok if second middleware would just
ctx.body = 'ok'and no error or warning would appears. Reaction on absents ofawaitshould not depend on consequent code. - Reaction should be as soon as possible. Seen the crash on
ctx.throw()in the other part of a project is very confusing.
Edit: Possible solution could be to throw if next has been called, middleware is resolved and next is still pending with message says that this is the problem
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 17 (12 by maintainers)
here is the problem, you need to await or return next(), when you dont do that, the promise chain is ended, just change to
lack of an await/return is a bug. awaiting or returning it should fix it. otherwise, it’s just a dangling promise
Would it be sane to, in
koa-compose, make sure that the return is present (AFAIKasyncin ES@next always returns a Promise that resolves anyway)? Mini safeguard against newbie buggs that doesn’t affect run-time performance?