I'm learning Promises so that I can understand better before I try to use Firebase. I am new and I've been reading the following in regard to catch()
:
- Link one: An article with some exercises
- Link two: A question in SO in regard to why we always need a
catch()
after Promise chain - Link three: A question in SO in regard to the difference of
catch()
andthen()
From what I've read, I have taken the following conclusions:
catch()
is necessary at in every Promise chaining in case "unexpected exceptions" occurs. It seems like these "unexpected exceptions" can be detected by thefailureHandler
of mythen
. However, it cannot distinguish between "normal failure" from these types of failures. I assume that one of those "unexpected exceptions" is when you're trying to access some property of anull
element.- It seems like I can also do chaining of
then(successHandler, failureHandler)
and then proceed with acatch()
block to allow finer control, as mentioned in link two. This is useful when I want to do something else when something fails ("normal failure" in this case, not the "unexpected exceptions") and pass the rejected Promise to the nextthen
to process, thus potentially yielding very different results from the result had the failed part succeeded. I can also catch "unexpected exceptions" by usingcatch()
at the end of the chain in case something failed inside mysuccessHandler
orfailureHandler
.
As you can see from my conclusions, I have very little understanding of what errors might occur. I mentioned null
exception as one of the examples of "unexpected exceptions" (is this assumption even correct?). However, what other errors do failureHandler
detect and what other "unexpected exceptions" do catch()
detect?
I also mentioned above that [then
] cannot distinguish between normal failure from these types of failures. Is that correct? If it is, why is it important?
EDIT
After reading some more, it seems like if a Promise is rejected on the top of the chain, the then
s following are ignored and I immediately go to the catch()
block. This means that my conclusion above: This is useful when I want to do something else when something fails and pass the rejected Promise to the next then
to process is incorrect. If that is the case, if I already have a catch()
at the end of my chain, I no longer need a failureHandler
for each of my then
block. However, it is mentioned in link three:
The argument is that usually you want to catch errors in every step of the processing, and that you shouldn't use it in chains. The expectation is that you only have one final handler which handles all errors - while, when you use the "antipattern", errors in some of the then-callbacks are not handled.
However, this pattern is actually very useful: When you want to handle errors that happened in exactly this step, and you want to do something entirely different when no error happened - i.e. when the error is unrecoverable. Be aware that this is branching your control flow. Of course, this is sometimes desired.
I took my conclusion that the rejected Promise will be passed to the next then
to process because I read the above. So what does and you want to do something entirely different when no error happened - i.e. when the error is unrecoverable mean?