llodavid
llodavid

Reputation: 108

Why should you wrap checked exceptions in lambda's in an unchecked exception?

I've been a Java developer for about two years now and if there's one thing I really love about the language it's the stream API. It makes my code so much more fluent, consise and readable.

The one thing that bothers me though is how exceptions are supposed to be handled when working with lambda's. I've read several articles on the subject and have seen several questions on StackOverflow. The general consensus seems to be that you have to wrap the method call to catch the checked exception and rethrow an unchecked exception instead. (like so:https://www.oreilly.com/ideas/handling-checked-exceptions-in-java-streams )

But I've yet to read or understand why this is a good idea. The advantage of checked exceptions is that the caller knows what to expect. I was taught that whenever you want to enforce business rules, checked exeptions is the way to go. Unchecked exceptions should be reserved for those cases where the application cannot recover from the exception. So why did they pretty much force us to use unchecked exceptions when working with streams? This seems like a big flaw at first glance, right?

I'm currently writing a SOAP webservice and a big advantage is that all possible business faults that can be thrown are well defined. The client can respond accordingly to the exceptions being thrown. Throwing a runtime exception would cause the client to receive a SOAPFaultException not knowing what the heck went wrong or how to handle it.

I could use a global exception handler and catch all the possible RTE's (given I don't forget some) and then once again rethrow them as one of the checked exceptions defined in the XSD/WSDL. But I have a hard time enough convincing my senior colleagues of the benefits of functional programming and telling them to wrap their checked exceptions in unchecked exceptions, only to turn them back into checked exceptions is definitely not going to help my plight.

So why is catching checked exceptions in lambda's and wrapping them in unchecked exceptions considered the good way to do it? There are very few other scenario's where we would really catch a checked exception and throw an unchecked exception. So why is it considered to be the good option when working with lambda's? Is it really because it is the only possible way to do so (safe for a few dirty workarounds like Lombok's @SneakyThrows) given the language's limitations? And then how are you to handle all these unguided missiles?

Upvotes: 4

Views: 677

Answers (1)

Stephen C
Stephen C

Reputation: 718758

Why should you wrap checked exceptions in lambda's in an unchecked exception?

Short answer: because you have to. (Pretty much.)

So why did they pretty much force us to use unchecked exceptions when working with streams? This seems like a big flaw at first glance, right?

Without going into the history and the debate about whether checked exceptions were or were not a mistake ...

The handling of exceptions in streams and lambdas is actually a direct consequence of the general design of Java exceptions and exception handling. The latter cannot be changed: it would be too disruptive for Oracle's existing Java customer base. Therefore we are stuck with this for the foreseeable future.

Is it really because it is the only possible way to do so (safe for a few dirty workarounds like Lombok's @SneakyThrows) given the language's limitations?

Yes, it is the only way. Whether it is a good way or not.

And then how are you to handle all these unguided missiles?

One way is to simply let the unchecked (or sneaky checked) exception propagate. In most cases the application or thread will crash, and you can use the stacktrace in the log file to find / fix the root cause. This assumes that the original checked exception is not "expected" and therefore not really recoverable.

If you are trying to make your application recover from the checked exception:

  • For a wrapped exception, you can catch RuntimeException then use ex.getClass() and ex.getCause() to decide what to do.

  • For a sneaky checked exception, you can catch Exception and use instanceof to discriminate the (expected) sneaky checked exceptions from the unchecked ones.

Upvotes: 1

Related Questions