Early exit from a javascript promise

hello all - earlier this year i posted this sitepoint question about how to structure my promise.

one of the stackOverflow answers suggested something like this using throw new Error:

firstPromise.then ( result => ()  {
    // process result
    if  ( time to exit early for whatever reason ) {
        throw new Error ( 'Normal exiting after  firstPromise');
   }
    return secondPromise(result);
})
.then ( result2 =>  {
   // process result2
    if  ( time to exit early for whatever reason ) {
        throw new Error ( 'Normal exiting after secondPromise');
   }
    return thirdPromise(result2);
})
.then ( result3 => {
   // process result3
    return lastPromise(result3);
})
.catch ( catchVal => { console.log(catchVal); 
})
;

using throw new Error certainly works very well, except what if the condition is not really a runtime error at all, but rather a normal situation? using this sorta gives some scary-looking message (as it should).

it would be nice not to see all the error messages in the console. i should think you could do a “jump to end” or even like a break; to a named point.

note: i really have no control over how all these functions work or how they are written since they are part of a package. and i would like to not have to break anything up using functions unless i absolutely have to.

Maybe create custom error type that signals an early exit?

class ExitEarly extends Error {
    constructor(message) {
        super(message);
        this.name = "ExitEarly";
    }
}

firstPromise.then(result => {
    if (/* time to exit early for whatever reason */) {
        throw new ExitEarly('Exiting after firstPromise');
    }
    return secondPromise(result);
})
.then(result2 => {
    if (/* time to exit early for whatever reason */) {
        throw new ExitEarly('Exiting after secondPromise');
    }
    return thirdPromise(result2);
})
.then(result3 => {
    return lastPromise(result3);
})
.catch(err => {
    if (err instanceof ExitEarly) {
        // handle early exit gracefully
    } else {
        // handle real errors
        console.log(err); 
    }
});

This way, you can differentiate it from actual errors in your catch block?

1 Like

@Pepster64, THANK YOU! i have not tried your solution yet, but it looks absolutely BRILLIANT.

funny, but i should think this sort of promise usage would be very common. but for now, i plan to incorporate your suggestions with a footnote giving you full credit. future generations will look at my code and think of you…:sunglasses:

I don’t understand what your construct should be good for at all. If you don’t want the second or third promise to be executed just don’t call it. Return null instead of result (or even other data to explain the promise chain has interrupted.) there is no need of using exceptions in this case

@Thallius - most of the time i want to run all the way through the promise stack, but certainly not all the time.

@Pepster64 suggestion appears to be doing exactly what i need it to do, that being to have a graceful way to exit the promise stack. in other words, its not really an error.

its beyond me why we cannot have something like jumpToFinally('exiting'); or jumpOut('exiting'); rather than calling a perfectly common/normal situation an error. /rant

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.