You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5:HttpInterceptor响应拦截器遇504超时重试问题

解决HttpInterceptor重试超时请求时状态码为0的问题

Hey there! Let's break down why you're seeing a status code of 0 instead of the expected 504, and how to fix it alongside your Auth interceptor.

为什么状态码会是0?

When Angular encounters a network-level error (like a timeout, CORS issue, or the browser aborting the request before receiving a full response), the HttpErrorResponse will show a status of 0—even if your browser's dev tools display a 504 Gateway Timeout. This happens because the browser doesn't expose the full server response details to Angular in these edge cases.

The twist with your scenario is that your Auth interceptor is interacting with this error flow, which might be altering how the error is passed through the interceptor chain.

修复步骤

1. 确保拦截器顺序正确

Angular runs interceptors in the order you provide them for request handling, and in reverse order for response/error handling. For your retry logic to work with authenticated requests:

  • Add your Auth interceptor first (so it attaches the auth header before the request reaches the retry logic)
  • Add your retry interceptor second (so it catches errors after the Auth interceptor has processed the response)

Example in your app module:

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: RetryInterceptor, multi: true }
]

2. 修正Auth拦截器的错误处理

If your Auth interceptor uses catchError, make sure it only handles specific errors (like 401 Unauthorized) and re-throws all other errors without modifying them. A common mistake is overwriting the error object, which can wipe out status code details or set status to 0.

Bad example (avoid this):

catchError(err => {
  if (err.status === 401) {
    // Handle token refresh/login redirect
  }
  // ❌ This replaces the original error with a status 0 response
  return throwError(() => new HttpErrorResponse({ status: 0 }));
})

Good example:

catchError(err => {
  if (err.status === 401) {
    // Handle your auth logic here (e.g., refresh token)
  }
  // ✅ Re-throw the original error so downstream interceptors can process it
  return throwError(() => err);
})

3. 优化重试拦截器的错误判断

Since you might get status: 0 even for a 504 error, update your retry logic to check for both cases, plus additional error context (like error messages or event type):

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, of } from 'rxjs';
import { mergeMap, delay, take, retryWhen } from 'rxjs/operators';

@Injectable()
export class RetryInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      retryWhen(errors => {
        return errors.pipe(
          mergeMap((err: HttpErrorResponse) => {
            // Check for 504 OR status 0 (network/timeout error) with relevant context
            const shouldRetry = 
              err.status === 504 || 
              (err.status === 0 && (err.message.includes('timeout') || err.error instanceof ProgressEvent));
            
            if (shouldRetry) {
              // Retry after 1 second, adjust delay as needed
              return of(err).pipe(delay(1000));
            }
            // Don't retry, pass the error through
            return throwError(() => err);
          }),
          take(3) // Limit to 3 retries, adjust as needed
        );
      })
    );
  }
}

4. 检查CORS配置(如果适用)

If your server returns a 504 but Angular still gets status: 0, verify your server's CORS settings. Ensure the Access-Control-Expose-Headers header includes any necessary response headers, and that the server allows the client to access the 504 status code. Some servers block exposing error status codes via CORS by default.

总结

The core issue is likely a combination of Angular's handling of network errors and your Auth interceptor altering the error flow. By fixing the interceptor order, ensuring errors are passed through unmodified, and expanding your retry logic to account for status: 0 cases, you should get your timeout retry functionality working as expected.

内容的提问来源于stack exchange,提问作者HobojoeBr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:22:01