1

I want to catch HTTP errors in my global exception handler.
The exception handler is working for most exceptions, but observable exceptions are not caught. The exceptions that I want to catch are HTTP exceptions.

This is how I tried sending the HTTP observable error to the exception handler.

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

}

This, of course, doesn't work because the code after the throw is not executed.
But the exception that is thrown is also not caught, probably because this is done in an observable.

Is there a way to catch the exception in the global exception handler, and the request is still available at subscribe((res) => {}, (errRes) => {/*here*/})?

2
  • what do you mean by global exception handler? Commented Jul 20, 2017 at 8:58
  • @Maximus angular.io/api/core/ErrorHandler A custom ErrorHandler Commented Jul 20, 2017 at 9:58

2 Answers 2

6

You need to return new observable, created from scratch:

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

}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I was able to throw the exception after observer.error(error) and catch it successfully in the error handler.
2

You can simply inject the global error handler and call handleError on it:

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

6 Comments

Injecting the error handler is not working because there are dependency injection parameters in the constructor.
can you clarify what you mean? and can you post your solution?
I think that @JanWytze want to keep same list of constructor parameters, as in Http, to avoid using factory in module.
@MaciejTreder, yeah, right, thanks. They use their custom HTTP service instead of default I guess, correct?
@MaciejTreder, yeah, that's so annoying to guess... In that case your solution is correct, this is how it's done in the sources. Upvoted)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.