Angular2:HTTP错误处理

时间:2016-04-14 16:12:38

标签: typescript angular rxjs

我正在尝试重现以下基于Angular2的Ionic2应用程序中使用Angular 1.x拦截器和承诺成功实现的行为:

  1. 拦截HTTP请求错误
  2. 如果状态代码为401,则

    一个。再提出注册客户的请求。这将提供一些我随后可以附加到每个请求的令牌。

    湾重试orignal请求并通过promise / observable将结果提供给调用者

  3. 如果错误状态不是401,只需让流程正常通知来电者

  4. 注意:注册过程不需要用户的任何干预(无需登录),因此我希望它对用户完全透明。我首次加载应用时注册一次,但会话最终会过期,我需要自动重新注册。

    这是原始的Angular 1实现(我只包含拦截器的responseError部分):

    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;
        }
    }
    

    现在,我已经包装了Angular2的HTTP服务,我可以做一些简单的事情,比如为每个请求添加一个标头。但是,我正在努力使用Angular2和Observables重现相同的行为。

    到目前为止我的尝试,这是我的服务将调用的HTTP包装器的请求方法:

    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;
    }
    

1 个答案:

答案 0 :(得分:5)

您可以使用observables的flatMap运算符初始化会话后再次执行请求:

    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;
}