Promises - breaking the then()-chain


I have a program, that goes pretty much like this:

    .then(doB, rejectHandler)
    .then(doC, rejectHanlder)
    .then(doD, reject Handler)

rejectHandler() is just a short function that displays a generic error message to the user, and prints a rejection message (i.e. the string that I pass as and argument for doA, doB, doC and doD 's reject function) to the console. It works, but i would like to improve it, by showing the user which step exactly failed. However, every then() in the chain is called no matter if the previous promise was fulfilled or rejected. This means, that if my doA() returns a rejected promise for some reason, all three then()'s will fire, calling rejectHandler() three times. This means that no matter which promise was initially rejected, my user will only receive a rejection msg for doC (…right?).

Now I could possibly modify rejectHandler() so it reacts different to each rejection, but it would be painfully verbose and it wouldn’t work for bigger apps. Also, truth to be told, if any of the do*() functions returns rejected promise, there is absolutely no point in starting the next step. So is there any way that I could break the then-chain? I.e. if rejectHanlder() was called, don’t call subsequent then()'s?

On the side note, I’m using fetch API in this program. In order to use it as a fulfillment handler for one of then()'s, I had to wrap it into function. A simple thing like this works:

function fetchWrapper(url){
    return fetch(url);

But I wanted to give it some custom rejection message. So far the best way I found is this:

function fetchWrapper(url){
    return fetch(url)
                return Promise.resolve(data);
                return Promise.reject("My custom message");

It works, but looks really clumsy. Any better ways to do it?

Thanks in advance.

Would something like this work for you?

  //results is an array of the results you get from doA, doB, doC, doD
  //if an error occurs in A B C or D it will bubble up here and you can handle it

if an error occurs in doA, doB, doC or doD it will bubble up into the catch method and you can handle it how you please

I don’t think so. Each subsequent function need data from previous function. I don’t think I can achieve that with Promise.all

I’d suggest you reading mdn docs about promises (especially about catch)

I’ve created a playground for you.
Try to comment/uncomment line 36:

throw new Error('handled')

as observe what happens.

Have fun.

1 Like

Ha! Got it working, thanks to that playground. There are still some little gotchas that I don’t quite understand, and my solution seems a bit hacky (for example, I return a rejected promise, instead of throwing an error in my rejectHandler), but I got it working exactly as intended. Thanks a lot mate!

Hey, I know it’s been a while, since you posted it, bu can you share your solution? I think I encounter a similar issue.
Thanks in advance!