Angular 2 улавливает наблюдаемую ошибку http в производном классе

Я хочу перехватывать ошибки 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);
        });
    }

}

Это, конечно, не работает, потому что код после броска не выполняется.
Но выбрасываемое исключение тоже не перехватывается, наверное, потому что это делается в наблюдаемом.

Есть ли способ поймать исключение в глобальном обработчике исключений, и запрос все еще доступен в subscribe((res) => {}, (errRes) => {/*here*/})?


person Jan Wytze    schedule 20.07.2017    source источник
comment
что вы подразумеваете под глобальным обработчиком исключений?   -  person Max Koretskyi    schedule 20.07.2017
comment
@Maximus angular.io/api/core/ErrorHandler Пользовательский обработчик ошибок   -  person Jan Wytze    schedule 20.07.2017


Ответы (2)


Вам нужно вернуть новую наблюдаемую, созданную с нуля:

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

}
person Maciej Treder    schedule 20.07.2017
comment
Спасибо! Я смог создать исключение после observer.error(error) и успешно перехватить его в обработчике ошибок. - person Jan Wytze; 20.07.2017

Вы можете просто внедрить глобальный обработчик ошибок и вызвать для него 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);
        });
    }
}
person Max Koretskyi    schedule 20.07.2017
comment
Внедрение обработчика ошибок не работает, потому что в конструкторе есть параметры внедрения зависимостей. - person Jan Wytze; 20.07.2017
comment
можешь пояснить, что ты имеешь в виду? а можешь выложить свое решение? - person Max Koretskyi; 20.07.2017
comment
Я думаю, что @JanWytze хочет сохранить тот же список параметров конструктора, что и в Http, чтобы избежать использования фабрики в модуле. - person Maciej Treder; 20.07.2017
comment
@MaciejTreder, да, верно, спасибо. Я думаю, они используют свой собственный HTTP-сервис вместо стандартного, верно? - person Max Koretskyi; 20.07.2017
comment
@Максимус, я не знаю. Я тоже так думаю ;) - person Maciej Treder; 20.07.2017
comment
@MaciejTreder, да, это так раздражает гадать ... В этом случае ваше решение правильное, вот как это делается в исходниках. Проголосовал) - person Max Koretskyi; 20.07.2017
comment
@Максимус Спасибо :) - person Maciej Treder; 20.07.2017