Angular2: HTTP error handling

I am trying to reproduce the following behavior that I have successfully implemented using Angular 1.x and promises interceptors in an Ionic2 application based on Angular2:

  • Intercepting HTTP Request Requests
  • If the status code is 401, then

    a. make another client registration request. This will provide some token that I can subsequently bind to each request.

    b. Repeat the orignal request and provide the result to the caller via promise / observable

  • If the error status is something other than 401, just let the thread normally call

Note. The registration process does not require user intervention (without login), so I want it to be completely transparent to the user. I register once when the application loads first, but the session expires eventually, and I need to re-register automatically.

This is the original implementation of Angular 1 (I only include the responseError interceptor part):

 responseError : function(rejection){ if(rejection.status == 401){ $log.info('Intercepting unauthorized 401 response. Will try to re-register the session and retry the request.'); var security = $injector.get('SecurityService'); var $http = $injector.get('$http'); return security.registerSession().then(function(){ return $http(rejection.config); }); }else{ return rejection; } } 

Now I have wrapped an Angular2 HTTP service, and I can do simple things like adding a header for each request. However, I'm struggling to reproduce the same behavior using Angular2 and Observables.

My attempt so far is the request method of my HTTP wrapper that my services will call:

 request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { let req: Request = this.buildRequest(url, options); this.beforeCall(req); var observable = this.http .request(req) .retry(3) .catch(res => { debugger; console.log("ERROR! " + res.status); if(res.status == 401){ this.logger.log('Unauthorized request. Trying to register the session and then retry the request.'); return this.securityService.registerSession().subscribe(() => { // What to do here so the client gets the result of the original request ?? }); } }) .do((res:Response) => { this.afterCall(req, res) }); return observable; } 
+6
source share
1 answer

You can run the query again after initializing the session using the observable flatMap operator:

  var observable = this.http .request(req) .retry(3) .catch(res => { debugger; console.log("ERROR! " + res.status); if(res.status == 401){ this.logger.log('Unauthorized request. Trying to register the session and then retry the request.'); return this.securityService.registerSession().flatMap(() => { return this.http.request(req); // <-------- }); } }) .do((res:Response) => { this.afterCall(req, res) }); return observable; } 
+5
source

All Articles