Skip to content
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

尽管使用了统一的错误处理机制,但是在第17个例子中,没有爆出想要的错误的提示 #27

Open
MyColourfulLife opened this issue Nov 22, 2017 · 2 comments

Comments

@MyColourfulLife
Copy link

MyColourfulLife commented Nov 22, 2017

比如运行第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中的处理错误的中间件处理。

@MyColourfulLife
Copy link
Author

MyColourfulLife commented Nov 23, 2017

感谢老师提示。

使用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);

@xugy0926
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants