Angular - 拦截你的http错误
简洁明了地管理http错误
Http拦截器的基本流程
由于错误在任何应用程序中都会时常发生,所以应该实现一个合适的错误处理系统。在这篇文章中,我们将重点讨论不同类型的http错误,以及我们如何对它们进行相应的处理。
http错误类型
有许多原因导致http请求失败。网络连接不良、网址不正确或请求的服务器目前不可用,这只是其中的几个例子。一般来说,错误可以分为两种类型:服务器端和客户端错误。
这两种类型都需要不同的处理方式,因为我们这些客户负责后者,我们可以用不同于前者的方式来处理它们。对于服务器端的错误,我们只能传递我们从服务器上收到的相应的错误信息或尝试重试,因为服务器可能只是暂时不可用。
然而,在客户端,我们可能使用了一个错误的URL或丢失了一个参数,我们需要修复它。
在这两种情况下,为用户提供一致的错误信息同样重要,为此,全局处理也是合适的。
Http拦截器
通过所谓的HttpInterceptor ,Angular为我们提供了一种转换http请求和响应的方法。
通过该接口,我们可以实现intercept ,该方法会在通过我们的应用程序发出的每一个HTTP请求中被自动调用。这使我们能够用一个拦截器来实现中央错误处理。
拦截器有以下参数。
- req - 要处理的外发请求对象。
- next - 链中的下一个拦截器,如果链中没有拦截器,则为后端。
- 返回:一个事件流的可观察对象。
我们来看看一个例子。
Http错误处理程序
我们可以通过使用AngularCLI 的以下命令来创建一个新的拦截器。
ng generate interceptor http-error
我通常把拦截器放在一个包含全局功能的CoreModule 中,并在应用启动时立即加载。拦截器必须在该模块中注册。我们可以通过把它添加到提供者数组中来实现。
multi 属性必须设置为true ,因为可能有多个拦截器使用HTTP_INTERCEPTORS 注入令牌。你可以在下面的StackBlitz例子中找到这一切。
接下来,我们实现intercept 方法,将RxJScatchError 操作符添加到请求中,用于我们的错误处理逻辑。
在catchError,我们检查错误是否是ErrorEvent 的实例,在这种情况下,类型是未知的,可能是我们的代码出了问题。否则,我们可以评估来自服务器的响应并进行相应的处理。
如前所述,无论错误类型如何,向用户显示一个有意义的信息是很重要的。为此,我们可以定义一个接口,让所有的错误信息有一个一致的结构,比如说像下面这样。
我们有一个可选的标题 ,我们可以使用这个标题 ,例如,显示一个祝酒词。然后是错误信息本身,不同的严重程度和http响应代码。现在让我们把这个接口添加到我们的拦截器中。
我们对这两种类型的错误进行转换,然后重新抛出错误,这样它就可以由最初触发请求的相应服务来处理。
接下来,我们可以为上面提到的特定响应代码整合重试逻辑。http-requests的重试可以很简单地用RxJS实现。有两个操作符:retry和retryWhen 。
它们中的任何一个都可以用来重试一个给定次数的可观察序列。在这种情况下,retryWhen 操作符更合适,因为我们可以处理任意的条件,而不仅仅是重试的次数。
对于我们的重试策略,我们可以创建一个自定义操作符。
可定制的重试,增加持续时间(来源:Learnrxjs)
我们可以使用三个参数来配置我们的操作符。首先是尝试的次数,其次,我们可以使用scalingDuration ,在尝试之间创造一个延迟,第三,可以排除任何http代码,例如404,因为重试例如 "404 - not found "是没有意义的。
现在可以简单地将新的操作符和retryWhen 一起插入到我们的拦截器的管道中。
请看StackBlitz上的完整例子。
下一步是什么
下面是一些进一步改进的想法。
- 为你的错误信息添加国际化(i18n),以支持多种语言,例如通过使用ngx-translate。
- 改进重试逻辑,为用户显示一个提示,说明他们是否要重试请求。