【问题标题】:Angular 2 catch observable http error in derived classAngular 2 在派生类中捕获可观察的 http 错误
【发布时间】:2017-07-20 08:55:35
【问题描述】:

我想在全局异常处理程序中捕获 HTTP 错误。
异常处理程序适用于大多数异常,但不会捕获可观察到的异常。我要捕获的异常是 HTTP 异常。

这就是我尝试将 HTTP 可观察错误发送到异常处理程序的方式。

import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Http, Response, RequestOptionsArgs } from '@angular/http';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { HttpException } from '../exceptions/http-exception';
import {Observable} from 'rxjs/Observable';


@Injectable()
export class HttpErrorService extends Http {

    constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs) {
        return super.request(url, options).catch((error: Response) => {

            // Bypass lint.
            fail();
            function fail() {
                // Here I want to throw the exception to send it to the exception handler, but it should also execute return Observable.throw(error); So I can catch the exception at the subscribe.
                throw new HttpException(error);
            }

            return Observable.throw(error);
        });
    }

}

这当然是行不通的,因为 throw 之后的代码没有被执行。
但是抛出的异常也没有被捕获,可能是因为这是在 observable 中完成的。

有没有办法在全局异常处理程序中捕获异常,并且请求仍然可以在subscribe((res) => {}, (errRes) => {/*here*/})获得?

【问题讨论】:

标签: angular typescript exception-handling angular2-observables


【解决方案1】:

您需要返回从头开始创建的新可观察对象:

@Injectable()
export class HttpErrorService extends Http {

    constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs) {
        return Observable.create(observer => {
            super.request(url, options).subscribe(
                res => observer.next(res), //simply passing success response
                err => { //error handling
                       console.log("global error handler");
                       observer.error(err); //passing error to the method which invoked request
                },
                () => observer.complete() //passing onComplete event to the method which invoked request
             );
        });
    }

}

【讨论】:

  • 谢谢!我能够在observer.error(error) 之后抛出异常并在错误处理程序中成功捕获它。
【解决方案2】:

您可以简单地注入全局错误处理程序并在其上调用handleError

export class HttpErrorService extends Http {

    constructor(errorHandler: ErrorHandler, backend: XHRBackend...) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs) {
        return super.request(url, options).catch((error: Response) => {

            // Bypass lint.
            fail();
            function fail() {
                // Here I want to throw the exception...
                const error = new HttpException(error);
                errorHandler.handleError(error); //<----------------- here!
            }

            return Observable.throw(error);
        });
    }
}

【讨论】:

  • 注入错误处理程序不起作用,因为构造函数中有依赖注入参数。
  • 你能澄清你的意思吗?你能发布你的解决方案吗?
  • 我认为@JanWytze 想要保持与 Http 中相同的构造函数参数列表,以避免在模块中使用工厂。
  • @MaciejTreder,是的,对,谢谢。我猜他们使用自定义 HTTP 服务而不是默认服务,对吗?
  • @MaciejTreder,是的,这太烦人了……在这种情况下,您的解决方案是正确的,这就是in the sources 的完成方式。赞成)
猜你喜欢
  • 1970-01-01
  • 2018-02-11
  • 2017-05-12
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
相关资源
最近更新 更多