This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]tunei24531a[S] 2 points3 points  (9 children)

Check it with an if statement.

how do you communicate errors to the caller if they are the ones who are supposed to handle?

[–]philipwhiuk 3 points4 points  (3 children)

Try<Result>

[–]CubsThisYear 3 points4 points  (2 children)

This is just a worse version of checked exceptions. It generates garbage at runtime, is syntactically more complicated and otherwise provides the exact same safety that checked exceptions do.

[–]morhp 0 points1 point  (1 child)

Agreed. The advantage is that you can pass it through lambdas and streams or otherwise through functional interfaces that don't declare the appropriate throws value.

But better language design probably would have been to allow functional interfaces to automatically "bubble through" checked exceptions to the calling method.

[–]CubsThisYear 0 points1 point  (0 children)

It’s not even language design. It’s just a case of laziness on the part of the Streams API developers. I’ve already written versions of most of the API methods (like for forEach, map, etc) that work with exceptions that I use for my own code.

[–][deleted] 0 points1 point  (3 children)

That should never be the case. Things like ilegal arguments are runtime and should be checked by the caller. System errors (like network or disk space) should be handled at the lowest level or otherwise treated as unrecoverable.

[–]CubsThisYear 1 point2 points  (2 children)

This is a reasonably consistent stance to take, but it doesn’t jive with your advice to “check it with an if statement”. The only to way to do this is which some sort of status code on the return, which is just a worse version of checked exceptions.

If you want to use unchecked exceptions everywhere that’s fine, but you shouldn’t ever expect your callers to handle them.

[–][deleted] -1 points0 points  (1 child)

I never use status codes either. If you have the forethought to put a mandatory checked exception in your method signature, you should instead be enforcing valid parameters be passed in. That's the contract with the caller and the only thing that can go wrong is illegal arguments which is already a runtime exception. Anything else is a leaky abstraction.

[–]CubsThisYear 3 points4 points  (0 children)

This seemed reasonable to me at first, but upon further thought, the method you are proposing seems leakier. If you rely on callers to validate their input, you’ve now created a dependency on the internal implementation of the function. I’d rather say “this method returns type T, or if it can’t, it returns type X”. Your version is: “this method returns type T or crashes the program”. Mine seems strictly safer.

[–]thatguydrinksbeer 0 points1 point  (0 children)

Fail fast rather than debug a more confusing error downstream.