My question is how errors are propagated through a series of then continuations to a catch continuation.
Promise.reject(new Error("some error"))
.then(v => v + 5)
.then(v => v + 15)
.catch(error => console.log(error));
Yes, as is clear from the spec:
then must return a promise.
promise2 = promise1.then(onFulfilled, onRejected);
onRejected is not a function and
promise1 is rejected,
promise2 must be rejected with the same reason as
In other words, it is not exactly that the intermediate
then's are "skipped", or that the promise "falls through" them (although one could sort of think of it that way); rather, the promises they return are rejected with the same reason as the input promise.
By the way, it is more accurate to call these "rejections", rather than "errors" (although, the "reason" for a rejection" would often be an error). Speaking of terminology, it would be more common to call these "handlers", not "continuations".