The most common pattern in languages with explicit error handling, is to simply return the error (possibly with some context added) in every function up to the point where the process was started (e.g. an HTTP endpoint handler, or the CLI's main function) to deal with it.
I'm not saying exceptions are good, but I am saying that they do represent the most common error handling pattern.
Right, this is largely the same idea. For things that have to be bubbled up, you wind up in the simplistic "single thread of execution by an operator" pattern. And, in that scenario, exceptions work exactly the same as just returning it all the way up. It is literally just making it easier to unwind the stack.
My assertion is that actual error handling in workflows doesn't work in that manner. Automated workflows have to either be able to work with the value where it was broken, or generally just mark the entire workflow as busted. In that scenario, you don't bubble up the exception, you instead bubble up an error code stating why it failed so that that can be recorded for later consideration. Along the way of bubbling up, you may take alternative actions.
I'm not saying exceptions are good, but I am saying that they do represent the most common error handling pattern.