angular2 - 多次处理相同的响应错误

时间:2016-07-24 12:56:02

标签: http typescript error-handling response

我正在构建一个angular2应用程序。我有一个名为HttpClient的全局服务,它在内置http服务被解雇之前处理所有请求。此服务还通过检查状态代码处理我的所有响应错误:

import { Injectable } from '@angular/core';
import { Headers, Http, Response, } from '@angular/http';

import { MessageProvider } from '../../providers/message/message.provider'

@Injectable()
export class HttpClient {

    private webApi = 'http://localhost:8080/api/v1/';

    constructor(
        private http: Http,
        private messageProvider: MessageProvider) { }

    get(url: string): Promise<Response> {
        return this.http.get(this.webApi + url, {headers: this.createAuthorizationHeader()})
                        .toPromise()
                        .catch(this.handleError.bind(this));
    }

    post(url: string, data: Object): Promise<Response> {
        return this.http.post(this.webApi + url, data, {headers: this.createAuthorizationHeader()})
                        .toPromise()
                        .catch(this.handleError.bind(this));
    }

    put(url: string, data: Object): Promise<Response> {
        return this.http.put(this.webApi + url, data, {headers: this.createAuthorizationHeader()})
                        .toPromise()
                        .catch(this.handleError.bind(this));
    }

    delete(url: string): Promise<Response> {
        return this.http.delete(this.webApi + url, {headers: this.createAuthorizationHeader()})
                        .toPromise()
                        .catch(this.handleError.bind(this));
    }

    private handleError (error: any) {

        var status: number = error.status;

        if(status == 401) {
            this.messageProvider.setMessage(error);
            this.messageProvider.message.text = "You have to be logged in to reach this page.";
        }


        let errMsg = (error.message)
            ? error.message
            : status
                ? `${status} - ${error.statusText}`
                : 'Server error';

        console.error(errMsg); // log to console instead

        return error;
    }

    private createAuthorizationHeader() {

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Accept', 'application/json');

        if (localStorage.getItem('token'))
            headers.append('Authorization', 'Bearer ' + localStorage.getItem('token'));

        return headers;
    }
}

现在,让我们假装调用组件是关于登录的:

import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';

import { Login } from '../../core/classes/login/login'

import { AuthenticationProvider } from '../../providers/authentication/authentication.provider'
import { MessageProvider } from '../../providers/message/message.provider'

@Component({
  selector: 'my-login',
  templateUrl: 'app/components/login/login.component.html'
})
export class LoginComponent implements OnInit, OnDestroy {

  @Input() login: Login;
  error: any;

  constructor(
    private authProvider: AuthenticationProvider,
    private route: Router,
    private messageProvider: MessageProvider) { }

  ngOnInit() {
    this.login = new Login();
  }

  ngOnDestroy() {
    this.messageProvider.setDefault();
  }

  onSubmit() {
    this.authProvider.login(this.login)
        .then(auth => {
            if (this.authProvider.isAdmin())
                this.route.navigateByUrl('admin/users');

            else if (this.authProvider.isLoggedIn())
                this.route.navigateByUrl('/');
            })
            .catch(error => {console.log(error);});
  }
}

在这种情况下,我不希望来自HttpClient的错误(“您必须登录才能访问此页面。”),而是更加自定义的消息,例如“找不到用户”。我知道我可以做类似以下的事情,但不再有任何错误:

onSubmit() {
    this.authProvider
        .login(this.login)
        .then(auth => {
            if (this.authProvider.isAdmin())
                this.route.navigateByUrl('admin/users');

            else if (this.authProvider.isLoggedIn())
                this.route.navigateByUrl('/');
            })
            .catch(error => {
                var status: number = error.status;

                if(status == 401) {
                    this.messageProvider.setMessage(error);
                    this.messageProvider.message.text = "No user found.";
                }
            });
}

那么有没有办法在HttpClient中的catch()函数中引起另一个错误?所以我可以在LoginComponent中再次处理错误。

1 个答案:

答案 0 :(得分:3)

我认为你可以使用catch方法来实际“映射”你的错误。如果您还要更新messageProvider,那么您可以...

.catch(error => {
    var status: number = error.status;
    var newError = {};
    if(status == 401) {
        this.messageProvider.setMessage(error);
        this.messageProvider.message.text = "No user found.";
        newError.errorMessage = "No user found.";
    }
    throw newError;
});

用这个例子证实:

  var obs = Observable.of(12);
  obs.map((value) => {
    throw "blah";
  }).catch((error) => {
    if(error === "blah") {
      throw "baz";
    } else {
     return Observable.of("Hello");
    }
  }).subscribe((value) => {
    console.log("GOOD: " + value);
  }, (error) => {
    console.log("ERR: " + error);
  });
  //Logs ERR: baz