I thought of Java only because I'd been reading essays about Java exceptions considered harmful, and then one day I recognised the problem it described, where to change one small function I had to do an absurd number of boilerplate-like edits elsewhere.
I found it quite thought-provoking about "type brittleness" with regard to aspects of the dynamic vs. static typing debate.
I've written in Haskell and SML too, where it didn't feel like the same level of brittleness. Perhaps it's to do with the size of applications and libraries, and how they evolve.
That's why I think of it as a software engineering getting-the-balance-right thing, rather than a correctness vs. prototype-in-a-hurry thing as static-vs-dynamic is often portrayed.
So one ends up putting a couple of catch all handlers in critical code paths, just in case.
Actually CLU checked exceptions, Modula-3 exception sets, C++ exception specifications.