最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to handledetect canceled requests in http interceptor Angular? - Stack Overflow

programmeradmin1浏览0评论

How do I handle cancelled requests in http interceptor? I have tried various methods from SO, but none of them seem to catch it.

This is how my interceptor is,

public intercept(req: HttpRequest<any>, next: HttpHandler) {
        const xyz = this._cookieService.get('xyz');
        const abc = this._cookieService.get('abc');

        let authReq;
        if (jwt === "undefined" || jwt === undefined) {
            authReq = req.clone({ headers: req.headers.set('Authorization', xyz) });
        } else {
            authReq = req.clone({setHeaders: { Authorization: 'bearer ' + abc } });
        }

        return next
            .handle(authReq)
            .pipe(
                catchError((err: HttpErrorResponse) => this.catchErrorHandler(err))
            );
    }

How do I handle cancelled requests in http interceptor? I have tried various methods from SO, but none of them seem to catch it.

This is how my interceptor is,

public intercept(req: HttpRequest<any>, next: HttpHandler) {
        const xyz = this._cookieService.get('xyz');
        const abc = this._cookieService.get('abc');

        let authReq;
        if (jwt === "undefined" || jwt === undefined) {
            authReq = req.clone({ headers: req.headers.set('Authorization', xyz) });
        } else {
            authReq = req.clone({setHeaders: { Authorization: 'bearer ' + abc } });
        }

        return next
            .handle(authReq)
            .pipe(
                catchError((err: HttpErrorResponse) => this.catchErrorHandler(err))
            );
    }

I have tried the do, finalize methods as well. Its that, my auth expires, and all the requests after that just collapse one by one, and the page breaks. I would like to handle it with code, so that the page doesn't break. Methods I have tried: https://stackoverflow./a/50620910/6630504 https://stackoverflow./a/55756885/6630504

Share Improve this question asked Sep 3, 2019 at 0:21 AijazAijaz 73019 silver badges50 bronze badges 5
  • Please share exactly how you are cancelling requests in your code. Also please share how you are handling errors in the service where this failing HttpClient is causing issues. – Alexander Staroselsky Commented Sep 4, 2019 at 3:54
  • I am not deliberately canceling the code. The browser cancels the code, in my case if the auth expires. – Aijaz Commented Sep 5, 2019 at 15:24
  • Have you determined why the requests are being cancelled? It's very difficult to help resolve this issue if there isn't a working example or a process to replicate this issue. – Alexander Staroselsky Commented Sep 5, 2019 at 15:36
  • I have similar problem. I have counter realted to count simualtenous calls to show wait screen. Now when call is cancelled spinner stay showing because one call has started but never ending. Or seems like that. Have you managed to solve your problem? – Janne Harju Commented Mar 11, 2021 at 9:37
  • There is fix in angular 11.2 github./angular/angular/issues/22324 – Janne Harju Commented Mar 11, 2021 at 11:19
Add a ment  | 

4 Answers 4

Reset to default 3

There is an RxJS operator called finalize.

Returns an Observable that mirrors the source Observable, but will call a specified function when the source terminates on plete or error. The specified function will also be called when the subscriber explicitly unsubscribes.

    return next
        .handle(authReq)
        .pipe(
            catchError((err: HttpErrorResponse) => this.catchErrorHandler(err)),
            finalize(() => console.log('finalize'))
        );

I was wondering the same thing for some time now and decided to look into it today.

When logging a cancelled request, the error looks like this:

{
    "headers": {
        "normalizedNames": {},
        "lazyUpdate": null,
        "headers": {}
    },
    "status": 0,
    "statusText": "Unknown Error",
    "url": "https://localhost:7258/api/pany/test-exception",
    "ok": false,
    "name": "HttpErrorResponse",
    "message": "Http failure response for https://localhost:7258/api/pany/test-exception: 0 Unknown Error",
    "error": {
        "isTrusted": true
    }
}

Notice the headers are empty and the status code is 0?

I found this when I search for what status code 0 means:

Practically speaking, status==0 for a failed XmlHttpRequest should be considered an undefined error.

this code could be the result of an error that happened even before the server is contacted.

Answer by whitneyland at What does it mean when an HTTP request returns status code 0?

While we will still need to determine the cause of the status 0, we could simply catch this error by:

next
  .handle(req)
  .pipe(
  catchError((err) => {
    if (err.status == 0) {
      // handle cancelled request here
      console.log(err);
    }
  }
})

Try this interceptor:

@Injectable()
export class RequestInterception implements HttpInterceptor {
  public constructor() { }

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const token = '';
    const currentLanguage = 'en';
    let headers;

    if (token) {
      headers = new HttpHeaders({
        "X-MDM-Token": token,
        "Accept-Language": currentLanguage
      });
    }

    request = request.clone({
      headers: headers,
      url: request.url || environment.serverUrl
    });

    return next.handle(request).pipe(
      map((event: any) => {

        if (event.status < 200 || event.status >= 300) {
          return Observable.throw(event);
        }

        return event;
      }),

      catchError((response: HttpErrorResponse, request) => {
        switch (response.status) {
          case 401:
            //
            break;
        }
        return throwError("Ошибка сервера RequestInterception!");
      })
    );
  }
}

If client canceled http request you will get 499 http code, it will be caught by:

if (event.status < 200 || event.status >= 300) {
      return Observable.throw(event);
}

I`ve doned it like this:

Interceptor code:

...
return next.handle(request)
  .pipe(
    onCancelled(() => {
      // cancelled request callback
    }),
  );
...

onCancelled function

function onCancelled<T>(callback: () => void) {
  return (obs: Observable<T>) => {
    let cancelled = true;
    return new Observable<T>(subscriber => {
      const sub = obs.subscribe(
        value => {
          if (value instanceof HttpResponse) cancelled = false;
          subscriber.next(value);
        },
        err => {
          cancelled = false;
          subscriber.error(err);
        },
        () => {
          cancelled = false;
          subscriber.plete();
        });
      return () => {
        if (cancelled) callback();
        sub.unsubscribe();
      };
    });
  };
}
发布评论

评论列表(0)

  1. 暂无评论