你想要统一处理错误异常来简化web应用程序。从Error继承包括http状态码的错误类,并使用中间组件来处理基于content type的错误。JavaScript有Error的构造函数,你可以继承它来表示特定类型的错误。在web开发中,一些错误越来越频繁地出现了:不正确的网址、不正确的参数查询参数或表单值、并发错误。这意味着你可以定义一些错误,来包括典型错误所提供的http代码。 你应该调用next(err),而不是在http路由中分离出一个错误条件的处理分支。接下来的代码会展示这一切是如何工作的。

怎么使用web服务查找正确的程序(统一处理错误异常来简化web应用程序)(1)

①在分离的文件中组织错误对象。

②确保路由的处理声明中包括了第三个参数,next。

③如果数据库API传递了一个错误,那么便提交返回结果。

④如果找不到记录,创建一个合适的错误实例。

在这个例子中,处理错误的类已经在单独的文件中定义,你可以在例子中找到。这个路由处理包括了第三个参数,next,在我们之前提到标准的req、res之后。

许多路由的处理程序会加载数据库中的数据,无论是从MySQL、PostgreSQL、MongoDB或者Redis,所以这个例子是基于一个通用的数据库异步API的。如果数据库API抛出一个错误,那么提早返回,并且将错误对象作为第一个参数调用next。这会把错误传递给下一个中间件。这个路由处理器有另外一部分的逻辑——如果在数据库中找不到记录,那么会实例化一个错误对象并使用next进行传递。下边的列表展示了如何继承一个Error

①创建通用的http错误类。

②使用util.inherits从Error继承。

③捕获堆栈信息。

④设置可以传递给浏览器的状态码。

⑤新增的http错误可以从httpError继承而来。

这里我们有选择性地创建了两个类。不仅仅只是定义了NotFound错误,还创建了httpError类,并且从它继承而来。这方便于我们跟踪错误是否与http相关,或者它也可能是其他错误。HTTPError这个基础的错误类可以从Error继承而来。

在NotFound错误中,我们捕获了堆栈跟踪信息,来帮助调试,同时设置了一个可以反馈给浏览器的状态码。

下面显示了如何在一个典型的Express应用程序中创建一个错误处理的中间件

怎么使用web服务查找正确的程序(统一处理错误异常来简化web应用程序)(2)

①如果在app.use使用了四个参数,那么第一个参数是错误对象。

②如果不是在测试模式中便打印堆栈跟踪信息。

③以期望的格式返回错误信息。

这个中间件相对简单,但是它已经包括了我们在生产环境中发现的一些需要调整的东西。为了在next中获取错误对象,请确保使用app.use回调函数的四个参数。同时请注意这个中间件在处理链条的最后,需要把它放在其他中间件和路由的定义之后。

可以选择性地打印堆栈跟踪信息,当特定的测试需要依赖错误信息时——错误作为测试的一部分被触发,堆栈信息应该是不可见的,你不希望堆栈信息搞乱了测试的输出。

因为需要在主要的应用文件中集中处理错误,所以根据条件返回不同的错误格式是一个很好的主意。如果应用提供HTML页面以及JSON API,那么这会是非常有用的。你可以使用app.format来处理,它用于检查在请求的Accept头部中的MIME type。JSON响应可能并不需要,但是你的API需要返回客户端可以预知的符合规则的错误信息——如果当你请求JSON时突然响应的是HTML,那么会很难处理。

在测试中,应该检查这些错误是否是你所需要的。下边的代码片段展示了mocha测试来确保404时以所期望的格式返回了所期望的内容

怎么使用web服务查找正确的程序(统一处理错误异常来简化web应用程序)(3)

①检查返回的状态码是否为期望的值。

②设置Accept头部来获取JSON。

③检查body是否是期望的格式。

这个代码片段包括了两个请求。第一个用例是我们得到了一个404错误,第二个是设置Accept头部来确保我们获取的是JSON。这是SuperTest的一个实现,将在响应中返回JSON,断言可以检查来确保我们拿到的对象是我们期望的格式。这个例子的源码可以在listings/web/error-handling中找到。

,