简体   繁体   English

Angular HttpStatus 4xx | 5xx 拦截器(有条件的)

[英]Angular HttpStatus 4xx | 5xx Interceptor (conditional)

In an Angular v.11 (also v.13 ) I need to write an Interceptor to show an error-text message to the user when the backend request return an error (status code 4xx or 5xx).在 Angular v.11(也是 v.13)中,我需要编写一个拦截器以在后端请求返回错误(状态代码 4xx 或 5xx)时向用户显示错误文本消息。

I know it is possible in Angular to write HttpInterceptors for this case, but I have a special case, where I must intercept and show the error-text message only if no explicit handlig for http-errors specified.我知道可以在 Angular 中为这种情况编写 HttpInterceptors,但我有一个特殊情况,只有在没有明确指定 http 错误的情况下,我才必须拦截并显示错误文本消息。

ex.前任。 code:代码:

Case-1:情况1:

this.http.get().subscribe(
   success(data),
   error(err)
);

Case-2:案例二:

this.http.get().subscribe(
   success(data)
);

For clarification, I need to show the error-text message only if there is no error(err) handling function defined (like in Case-2).为澄清起见,仅当未定义error(err)处理 function 时(如案例 2),我才需要显示错误文本消息。

Im not sure how to do that, and I am not sure if that is possible, but I think there should be a simple solution to that problem, that I cannot find by myself.我不确定该怎么做,我不确定这是否可行,但我认为应该有一个简单的解决方案来解决这个问题,我自己找不到。

Sounds like global error handling that is only applied if there's no local error handling.听起来像是只在没有本地错误处理的情况下才应用的全局错误处理。 It isn't exactly the type of architecture I'd go for, tbh.这不完全是我想要的架构类型 go,tbh。

The global error handling would somehow need to know when to apply its handling based on provided parameters or some other global service it could check (ie. local error handling would need to notify a service).全局错误处理将以某种方式需要知道何时根据提供的参数或它可以检查的某些其他全局服务应用其处理(即本地错误处理需要通知服务)。

I can't judge how much of your error handling you can change, but global error handling should handle generic errors that apply to a majority if not all HTTP requests.我无法判断您可以更改多少错误处理,但全局错误处理应该处理适用于大多数(如果不是全部)HTTP 请求的一般错误。 While the local one would handle specific cases exclusive to that particular request.而本地人将处理该特定请求所独有的特定情况。 That way you could run both error handlers without the risk of them interfering with each other.这样您就可以同时运行两个错误处理程序,而没有它们相互干扰的风险。

Since your problem seems to be UI related (ie. displaying error msg), the above approach would cover that as well.由于您的问题似乎与 UI 相关(即显示错误消息),因此上述方法也涵盖了这一点。 Global error handling would display some sort of generic error msg while you could add an additional error msg for your local handler.全局错误处理将显示某种通用错误消息,而您可以为本地处理程序添加额外的错误消息。 Both would be utilizing the same service for displaying error messages, I suppose.我想,两者都将使用相同的服务来显示错误消息。

Ignoring if its a good approach or not and focusing on the feasibility.忽略它是否是一个好方法并关注可行性。 Our goal is to only launch a generic handler when no other error handling is provided.我们的目标是仅在未提供其他错误处理时启动通用处理程序。

First let us understand better the tools to available to us, the HttpClient and the HttpInterceptor .首先让我们更好地了解我们可用的工具, HttpClientHttpInterceptor

  • HttpClient methods: create a HttpRequest based on the provided options and methods, attempts to resolve it and returns an Observable . HttpClient方法:根据提供的选项和方法创建一个HttpRequest ,尝试解析它并返回一个Observable
  • HttpInterceptor : it receives an HttpRequest and based on it performs something. HttpInterceptor :它接收一个HttpRequest并基于它执行某些操作。 It must return an Observable<HttpEvent<any>> .它必须返回一个Observable<HttpEvent<any>>

There is only one point connecting our 2 elements, the options that are used to create the HttpRequest that will be used by our HttpInterceptor .只有一点连接我们的 2 个元素,用于创建将由我们的HttpInterceptor使用的HttpRequest的选项。 Therefor, we cannot access the .subscribe() to check if there is an error handling callback or not.因此,我们无法访问.subscribe()来检查是否有错误处理回调。

In short, with just adding the error handling callback, it is not possible to perform what you are asking with the provided restrictions .简而言之,仅添加错误处理回调,就无法使用提供的限制执行您要求的操作。

The question then arrises, can we achieve it if we somehow lax our restrictions?那么问题来了,如果我们以某种方式放松限制,我们能做到吗? Well the answer lies in the options we pass to our HttpClient method.好吧,答案在于我们传递给HttpClient方法的选项。

We could pass an unique param to our interceptor, and use it to check if it needs the global error handler or not, like so:我们可以将一个唯一的参数传递给我们的拦截器,并使用它来检查它是否需要全局错误处理程序,如下所示:

  withGlobalError(): void {
    this.httpClient.get('www.foo.com', { params: { globalError: true } }).subscribe(
      _ => console.log('success')
    );
  }

  withoutGlobalError(): void {
    this.httpClient.get('www.foo.com').subscribe(
      _ => console.log('success'),
      error => console.log('Error handler in local scope', error)
    );
  }

In our HttpInterceptor we need to check if the param globalError exists and is true.在我们的HttpInterceptor ,我们需要检查参数globalError存在并且为真。 When so we can perform whatever we need.这样我们就可以执行我们需要的任何操作。

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(catchError(error => {
      if (request.params.get('globalError')) {
        console.log('Handling error in the Global Interceptor');
      }
      return throwError(error);
    }))
  }

This is the simplest approach to achieve what you want.这是实现你想要的最简单的方法。 It allows for global error handling to exist, while at the same time ensuring that every developer is aware of when it will be triggered.它允许存在全局错误处理,同时确保每个开发人员都知道它何时会被触发。

You can add a simple flag to the header when using HttpClient, then in the HTTP_INTERCEPTORS, you can check if this flag is existing, to decide to handle it or not!你可以在使用HttpClient时在header中添加一个简单的标志,然后在HTTP_INTERCEPTORS中,你可以检查这个标志是否存在,来决定是否处理它!

For eg :-例如:-

//In component or service file: -

this.http.get(
  'https://jsonplaceholder.typicode.com/todos/2',
  { headers: {'byPass': 'yes'} })
  .subscribe((response: any) => {
    console.log(response);
  }
);

//In interceptor: -

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // if there is byPass header, don't handle the error and remove this flag here
    if (req.headers.has('byPass')) {
        const newHeaders = req.headers.delete('byPass')
        const newRequest = req.clone({ headers: newHeaders });
        return next.handle(newRequest);
    } else {
        //Handle the error accordingly
        return next.handle(req);
    }
}

Still you should write a generic Error handler in interceptor only.你仍然应该只在拦截器中编写一个通用的错误处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NGiNX-没有返回足够的标头来显示错误(4xx,5xx)与成功(2xx) - NGiNX - Not returning sufficient headers for error(4xx, 5xx) Vs Success(2xx) Angular 2.如何使用Observable中的重定向处理4xx错误? - Angular 2. How to handle 4xx errors with redirect in Observable? Angular 4,&#39;{xx,xx}&#39;类型中缺少属性&#39;XX&#39; - Angular 4, Property 'XX' is missing in type '{xx, xx}' 返回4xx错误时的角度httpclient帖子,错误处理程序仅包含OK,没有解析json - angular httpclient post when returning 4xx error the error handler only contains OK, no json is parsed 如何使用router.navigate在observable中处理4xx错误。角2 - How to handle 4xx errors with router.navigate in observable. angular 2 在 protractor 测试中允许 4xx HTTP 状态代码 - Allow 4xx HTTP status codes in protractor tests 我键入内容时如何在输入中仅输入这样的数字XX.XXX,XX(货币)?(角度) - How to enter only a number like this XX.XXX,XX (currency)in the input while Im typing?(Angular) Angular 中请求参数的条件拦截器操作 - Conditional interceptor action upon request parameter in Angular 如何在 Angular 中基于 Request Uri 在自定义拦截器和 Msal 拦截器之间使用条件拦截器 - How to use conditional interceptor between custom Interceptor and Msal Interceptor based on Request Uri in Angular “仅数字指令”在 Chrome 49.xx.xx 及以下版本中不起作用 - 'Numbers only directive' not working in Chrome 49.xx.xx and below
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM