In a desktop application that is not allowed to totally crash, or at least has to crash kind of gracefully, checked exceptions are useful.
But in the world that most Java devs live in, which is various flavors of RPC server, failing requests is fine. If lots of requests fail, your monitoring infra should page someone, and that someone will go log spelunking and figure out what's broken.
Very occasionally it turns out that the thing causing the RPC failures is a recoverable exception, and then you should wrap the problematic stuff in a try/catch block. (Often you'll wind up having to detect the recoverable error case by conditioning on substrings in the exception message, which the library owners will arbitrarily change in future releases. So make sure to write regression tests so you'll catch this when you upgrade the library. Java is fun!) But 99% of the time the failure is "network is busted" or "config was invalid" or "hard disk failed" and you should not be defensively programming against all those possibilities.
> you should not be defensively programming against all those possibilities
This is where libraries and frameworks come into play - they defensively program against that for you. And wrap it all up in a simple interface with, well, checked exceptions.
If I need to write some bytes to an S3 bucket but the network is hosed, there's literally nothing useful I or any library can do until the network is back up.
RPC calls will fail, error logs should get written, and a monitor should get triggered, and someone should get paged so they can wake up and figure out why the network is hosed.
Nowhere in there is it useful for me to wrap all my S3 writes in try/catch blocks.
Error logs and monitors find out because the RPC fails, which causes an error to be logged and a failed request metric to be incremented. (The UncaughtExceptionHandler will do the same for stuff failing in background threads.)
If eventual consistency is important, enqueuing for retry has to be done BEFORE you try to write, not on write failure. If/when the write succeeds, you remove the item from the retry queue.
But in the world that most Java devs live in, which is various flavors of RPC server, failing requests is fine. If lots of requests fail, your monitoring infra should page someone, and that someone will go log spelunking and figure out what's broken.
Very occasionally it turns out that the thing causing the RPC failures is a recoverable exception, and then you should wrap the problematic stuff in a try/catch block. (Often you'll wind up having to detect the recoverable error case by conditioning on substrings in the exception message, which the library owners will arbitrarily change in future releases. So make sure to write regression tests so you'll catch this when you upgrade the library. Java is fun!) But 99% of the time the failure is "network is busted" or "config was invalid" or "hard disk failed" and you should not be defensively programming against all those possibilities.