ctx.set( 'Access-Control-Allow-Origin', '*' );
ctx.throw( 404 );
By using the code above, the header of Access-Control-Allow-Origin will not be sent with responding. Even though I can use res.statusCode instead, but I think the ctx.throw method should not remove response headers.
yes, that is by design. this should be handled by an error handler:
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.set('Access-Control-Allow-Origin', '*')
ctx.status = err.status
})
app.use(async (ctx) => {
ctx.throw(404)
})
According to my usage, you also put it in the try block like this
app.use(async (ctx, next) => {
try {
ctx.set('Access-Control-Allow-Origin', '*')
await next()
} catch (err) {
ctx.set('Access-Control-Allow-Origin', '*')
ctx.status = err.status
})
Otherwise, there will be no header you set in the normal code.
@mutoe @jonathanong @LvChengbin FWIW we use the second parameter in context.throw. YMMV

I had the same problem and solved it with this error handler middleware:
export default async (ctx, next) => {
return next().catch(err => {
const { statusCode, message } = err;
ctx.type = 'json';
ctx.status = statusCode || 500;
ctx.body = {
status: 'error',
message
};
ctx.app.emit('error', err, ctx);
});
};
more info here: https://stackoverflow.com/questions/52623644/how-to-make-koa-ctx-throw-use-application-json-rather-than-text-plain
any updates? I am also confused about this problem.
Feel free to use https://github.com/ladjs/koa-better-error-handler.
Most helpful comment
According to my usage, you also put it in the try block like this
Otherwise, there will be no header you set in the normal code.