I've used Scala in production codebases and it was common to just "let the EitherTs handle the exceptions". What ended up usually happening was swallowed exceptions that nobody bothered to handle and log because it was much less idiomatic Scala/FP to actually log what happened underneath than it was to return the first error that happened by short circuiting the EitherTs in for/yields (Maybe and do notation, for Haskellers). So we'd get 5xxes and log lines like "row not found" and have absolutely no idea why.
I see a lot of the same issues in Rust code today FWIW. People just keep bubbling up errors and at the toplevel say "fuck it" and dump them, without _actually_ building a reasonable error chain to offer the programmer a story behind how the error happened. The fact is, error handling in any language is tedious. Whether you do it with a sum type, a product type, or Go's error values, either way there's going to be lots of verbosity and boilerplate.
I see a lot of the same issues in Rust code today FWIW. People just keep bubbling up errors and at the toplevel say "fuck it" and dump them, without _actually_ building a reasonable error chain to offer the programmer a story behind how the error happened. The fact is, error handling in any language is tedious. Whether you do it with a sum type, a product type, or Go's error values, either way there's going to be lots of verbosity and boilerplate.