Home > Enterprise >  Promise chain of catchs
Promise chain of catchs

Time:09-16

I have this scenario:

controller.ts

methodA(): void {
    myServive.someMethod()
    .then( () => console.log("then") )
    .catch( e => {
        console.log("catch");
    });
}

service.ts

someMethod(): ng:IPromise<void> {

    const deferred = this.$q.defer<void>();

    return this.OtherService.otherMethod()
    .catch ( e => {
        deferred.reject(reason);
    }
}

otherservice.ts

otherMethod(): ng.IPromise<any> {
    return this.HttpService.get(url);
}

Test:

  • The otherMethod (otherService.ts) is getting an error from the HttpService.
  • The catch in someMethod (service.ts) is been executed.

Why, in the controller.ts, the then block is been executed?

CodePudding user response:

The catch is executed if some previous then (or catch) throws an error. If no errors, the code will execute the next then statement.

So you have this code:

methodA(): void {
    myServive.someMethod()
    .then( () => console.log("then") )
    .catch( e => {
        console.log("catch"); // No errors thrown, so the code will continue in the next then
    });
}

So you can throw an error inside the catch. The code will continue to the next catch:

methodA(): void {
    myServive.someMethod()
    .then( () => console.log("then") )
    .catch( e => {
        console.log("catch");
        throw new Error(e) // Some error happened! The code will continue in the next catch
    });
}

CodePudding user response:

Why, in the controller.ts, the then block is been executed?

because you caught the error and returned undefined in service.ts

It looks like you should just get rid of the catch/defer entirely in service.ts if you don't plan on handling any errors in there.

EDIT: If you want the catch to be handled in the controller, then just remove all the stuff from service.ts and just let do:

// service.ts
someMethod(): ng:IPromise<void> {
    return this.OtherService.otherMethod()
}

If you want to handle the catch in service.ts AND in the controller, then rethrow the error (or a new one):

// service.ts
someMethod(): ng:IPromise<void> {

    const deferred = this.$q.defer<void>();

    return this.OtherService.otherMethod()
    .catch ( e => {
        // you can either do:
        // throw e
        // which rethrows the same error (same as not having a catch in here at all)
        // or you can handle the error and throw a new one like:
        //
        // ...some error handling code
        // throw new Error('my new error');
    });
}

No matter which you choose, you don't need a deferred.

  • Related