learn-webapp-guideline
learn-webapp-guideline copied to clipboard
尽管使用了统一的错误处理机制,但是在第17个例子中,没有爆出想要的错误的提示
比如运行第17个案例, 在登录注册时故意输错 点击登录浏览器会报以下错误:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
而我们在处理api时,其实已经给出友好的错误的提示:比如用户不存在,密码有误等信息。而上面的错误不是我们想要的样子。
虽然使用了中间件errorHandel,但最终的错误处理是在app.js中处理的。 修改app.js 中错误处理的代码,比如新增自己对错误的处理,还是不行。甚至直接把render改为send都不奏效。
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
****新增代码开始****
if (err.status === 500 && req.baseUrl.startsWith('/api')) {
res.send(err);
return;
}
****新增代码结束****
// render the error page
res.status(err.status || 500);
****改动代码开始****
// res.render('error');
res.send(err);
****改动代码结束****
});
所以,该如何解决这个问题呢?
此外: 既然我们使用errorHandel去处理错误,为何不直接把res也传进来,遇到错误,直接返回响应?而不像案例中那样继续next将错误留给app中的处理错误的中间件处理。
感谢老师提示。
使用errorHandel作为应用中间件app.use()
整个项目瞥了一眼👁好多新语法,总的来说看起来很复杂。我看了errorhandle那个中间件,还是有些启发的。
知道了res.stauts().format();这个format会根据请求的Accept来返回相应的数据格式。
比如Accept是application/json就会走json那个函数等。详细点需要看下format这个函数。
于是,仿照老师的代码改造了下案例中的errorHandel中间件(这里没区分生产环境还是开发环境)
var errorHandle = function (err, req, res, next) {
const errorDetails = err.stack || err;
res.status(err.status || 500).format({
json() {
const errorInfo = {
details: err,
error: err.toString(),
};
res.send(errorInfo);
},
html() {
const message = `<pre>${errorDetails}</pre>`;
res.send(`<h1>500 Internal server error</h1>\n${message}`);
},
default() {
const message = errorDetails;
res.send(`500 Internal server error:\n${message}`);
}
});
}
module.exports = errorHandle;
然后把这个当做应用中间件,替代express给出的默认错误处理中间件。
在路由中也不用引入了,直接next(err),整体看起来更方便了。
了解err.response
alert的错误提示,没有给出想要的信息。打印err也没看出还有啥。
调试时是可以看到响应的,响应里真真切切的放着需要的信息。
可以怎么拿过来呢?
axios的then并没有捕获response,感觉很奇怪。
原来err还有个response属性。。。这里面包含了所有的响应信息,比如像这样(google浏览器调试界面,使用postman会简单些):
config:{...}
data:{details: {…}, error: "Error: 找不到用户"}
headers:{…}
request:XMLHttpRequest {…}
status:500
statusText:"Internal Server Error"
__proto__:Object
因此根据响应,修改客户端代码,即可弹出想要的信息。
alert(err.response.data.error);
补充事例:https://github.com/xugy0926/community/blob/master/src/middlewares/errorHandler.js