Koa 中的错误处理解析
不像express中在末尾处注册一个声明为(err,req,res,next)中间件的方式,koa刚好相反,在开头进行注册。
app.use(async(ctx,next)=>{ try{ awaitnext(); }catch(err){ ctx.status=err.status||500; ctx.body=err.message; ctx.app.emit("error",err,ctx); } });
这样程序中任何报错都会收敛到此处。此时可以方便地将错误打印到页面,开发时非常便捷。
+ctx.app.emit('error',err,ctx);
koa也建议通过app来派发错误,然后通过监听app上的error事件对这些错误做进一步的统一处理和集中管理。
app.on("error",(err,ctx)=>{ /*错误的集中处理: *log出来 *写入日志 *写入数据库 *... */ });
一个错误捕获并打印到页面的示例:
constKoa=require("koa"); constapp=newKoa(); app.use(async(ctx,next)=>{ try{ awaitnext(); }catch(err){ conststatus=err.status||500; ctx.status=status; ctx.type="html"; ctx.body=` ${status}${err} `; //emmit ctx.app.emit("error",err,ctx); } }); app.use(ctx=>{ consta="hello"; a="helloworld!";//TypeError:Assignmenttoconstantvariable. ctx.body=a; }); app.on("error",(err,ctx)=>{ console.error("Ooops..\n",err); }); app.listen(3000);
通过nodeserver.js启动后访问页面可看到命令行的错误输出。
如果使用pm2,可通过—no-daemon参数使其停留在在命令行以查看输出。
如果不使用上述参数,可通过pm2logs[app-name]来查看。
ctx.throw
朴素的抛错方式需要手动设置状态码及信息对客户端的可见性。
consterr=newError("errmsg"); err.status=401; err.expose=true; throwerr;
expose决定是否会返回错误详情给客户端,否则只展示状态对应的错误文案,比如500会在浏览器中展示为InternalServerError。
而通过ctx.throw这个helper方法会更加简洁。
上面的代码片段等价于:
ctx.throw(401,"errmsg");
如果不指定状态码,默认为500。5xx类错误expose默认为false,即不会将错误信息返回到response。
抛错时还可以传递一些额外数据,这些数据会合并到错误对象上,在处理错误的地方可以从error上获取。
app.use(ctx=>{ ctx.throw(401,"access_denied",{user:{name:"foo"}}); }); app.on("error",(err,ctx)=>{ console.error("Ooops..\n",err.user); });
参考
ErrorHandling
ctx.throw
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。