Live data from Hacker News

Unchecked Java: Say goodbye to checked exceptions

github.com

221–230 of 297 posts

Re: Unchecked Java: Say goodbye to checked exceptions

#221
post #117

Earlier quoted context omitted.

Lets be honest. The more likely thing is that either the coworker would use an unchecked exception or that they would change the callsite to: try { theUpdatedFunction(); } catch (MyNewCheckedException e) { logger.warn("Whoopsie doopsie", e) throw new SomeUncheckedException("Something failed, idk", e) } Which really is a zero sum game. The code still breaks the same way, but the checked exception gets eventually wrapp…

> That bug should have been caught by tests, code reviews and good communication. There's a reason we have compile-time checks. If you think compile-time checks should be replaced with additional tests, code reviews and good communication, then you want a scripting language, not a compiled language. You do not wrap checked exceptions in an unchecked one... unless you are a really bad Java programmer.

I've given a lot of time and benefit of the doubt to 'testing replaces static analysis' and not only do I know this is not true, but I'm also pretty sure that testing is fundamentally broken. It can't fix anything because it can't even fix itself.

Maybe a new testing paradigm will fix it, I certainly keep an eye out for them, but nothing so far. Property based testing is better, but mostly it just reminds me that we had Design By Contract 30 years ago.

Re: Unchecked Java: Say goodbye to checked exceptions

#222

Earlier quoted context omitted.

> That bug should have been caught by tests, code reviews and good communication. There's a reason we have compile-time checks. If you think compile-time checks should be replaced with additional tests, code reviews and good communication, then you want a scripting language, not a compiled language. You do not wrap checked exceptions in an unchecked one... unless you are a really bad Java programmer.

> You do not wrap checked exceptions in an unchecked one... unless you are a really bad Java programmer. I disagree -- this is the correct thing to do if you believe it is not possible for the checked exception to occur. (Catching it is wrong -- what would you do to correct something which you believe not to be possible? Forcing the caller to handle it is wrong -- if you don't know what to do with it, they sure won't…

> I disagree -- this is the correct thing to do if you believe it is not possible for the checked exception to occur.

If it is not possible to occur, then it should not be part of the API.

The only time I rethrow a checked exception as an unchecked exception is when the code is still under construction. The default of the eclipse code generator is to log and ignore caught transaction. I think wrapping into an unchecked one is the better default behavior for incomplete code under a "fail fast" policy.

Re: Unchecked Java: Say goodbye to checked exceptions

#223

One of the biggest flaws in C#, in my experience, is lack of checked exceptions. As an example, I wrote some very good code, carefully tested it, made it work flawlessly, then suddenly it started crashing. What happened? Someone made a change in a function I was calling, and it started throwing a new exception. This would have caused a compile error in Java, not a crash. More on checked vs unchecked exceptions here:…

> One of the biggest flaws in C#, in my experience, is lack of checked exceptions. I couldn't disagree more. Checked exceptions in Java have ruined a generation of programmers. The truth is, under checked exceptions, to satisfy the compiler the function that you called would declare that it throws a SomeModuleException and the programmer who wrote that function would put all his code in try/catch block that catches a…

From a type theory perspective, an exception is another type of return value that a function can have, and not documenting those in the function signature is absurd.

I have seen libraries that make network calls that do the following:

* Throw an exception on certain types of network errors * Return an HTTP error code for other types of network errors * Return an object with error set to true and an error string for other types of network errors

NONE of those was documented, it is crazy. This actually bite me in prod when an undocumented exception that we hadn't seen in over a year of uptime was finally thrown. I had to look at network logs to try and figure out why it was being thrown (no checked exceptions in JS!), which itself is absurd.

Re: Unchecked Java: Say goodbye to checked exceptions

#224
post #129
post #42

Earlier quoted context omitted.

> Checked exceptions are exactly analogous of Result/Either types. No, they aren't. They are not compositional. You may want to write `f(g())` but there's no way to write the parameter type of `f` to make this work (in Java). That's because checked exceptions are an "effect" that would require extending the Java type system.

How would you define f in a different language such that f(g()) worked? You couldn’t do that in Go, for instance.

> You couldn’t do that in Go, for instance.

You can – by making f accept g's return types, including the error. This is even being done in the Go standard library: https://pkg.go.dev/text/template#Must

Re: Unchecked Java: Say goodbye to checked exceptions

#225

Earlier quoted context omitted.

> One of the biggest flaws in C#, in my experience, is lack of checked exceptions. I couldn't disagree more. Checked exceptions in Java have ruined a generation of programmers. The truth is, under checked exceptions, to satisfy the compiler the function that you called would declare that it throws a SomeModuleException and the programmer who wrote that function would put all his code in try/catch block that catches a…

From a type theory perspective, an exception is another type of return value that a function can have, and not documenting those in the function signature is absurd. I have seen libraries that make network calls that do the following: * Throw an exception on certain types of network errors * Return an HTTP error code for other types of network errors * Return an object with error set to true and an error string for o…

> and not documenting those in the function signature is absurd

Exceptions can be thrown from anywhere. That's the documentation.

Re: Unchecked Java: Say goodbye to checked exceptions

#227
post #46

Reading through the comments, I realize this may be a minority view - but I like coding for the happy path and letting exceptional states crash. I find languages like go a bit harder to parse quickly because I always have to "unwrap" the happy path from all of the mixed in error handling. I'm sure I'd get used to it eventually, but I like that unchecked exceptions in Java are now an option!

This is what I like about Go and other more recent languages: Especially when networking or other IO is involved, things will go wrong. These languages don't try to circumvent this reality but instead embrace it by treating errors as very-first-class citizens. My error handling tends to be more thoughtful in those languages than in, say, Java.

Re: Unchecked Java: Say goodbye to checked exceptions

#228
post #113

Earlier quoted context omitted.

I mean, maybe? Fun degenerate cases to consider: Someone throws a Environment.Exit(0) into a random library you are using, instant pain. Someone throws an infinite loop into a library you are using, similar instant pain. There is no magic language trick that can prevent you from having to rerun all tests for your software if you update a dependency. Pretty much period. (I say this as someone that isn't really opposed…

If someone added an extra parameter to a function you're calling, when would you want to be alerted about it? At compile time? Or when you rerun all the tests? Hopefully, your answer is compile time. If so can you now understand why you would want to be alerted about a new exception getting thrown at compile-time as well?

> If so can you now understand why you would want to be alerted about a new exception getting thrown at compile-time as well?

The library code can already throw anything. OutOfHeap, over/underflow, div0, stackoverflow, threadinterrupted. The caller already knows the function can throw, and documenting one more flavour of throw doesn't tell the caller anything.

Re: Unchecked Java: Say goodbye to checked exceptions

#229
post #120
post #117

Earlier quoted context omitted.

Lets be honest. The more likely thing is that either the coworker would use an unchecked exception or that they would change the callsite to: try { theUpdatedFunction(); } catch (MyNewCheckedException e) { logger.warn("Whoopsie doopsie", e) throw new SomeUncheckedException("Something failed, idk", e) } Which really is a zero sum game. The code still breaks the same way, but the checked exception gets eventually wrapp…

Or, worse, you're reviewing a large diff, see the logger statement but don't notice that the junior whose code you're reviewing forgot to rethrow. Now you've accidentally entered uncharted territory where way more scarier things can happen to your application than just crashing. Of course this shouldn't happen, but it does.

that can be somewhat addressed with decent unit test coverage

Re: Unchecked Java: Say goodbye to checked exceptions

#230
post #165

Earlier quoted context omitted.

Exception based error handling is unsafe when they are unchecked exceptions. Checked exceptions however are as safe as Either, Try, Monads, Applicatives or whatever. You are forced to declare them in your method signature, the caller is forced to either handle them or rethrow them + declare them as well. And I guess this is precisely why so many developers hate them; they don't like the extra work they have to do to…

Checked (and unchecked) exceptions create an exponential number of control flow paths. Consider: try { throws_a(); r = grab_resource(); throws_b(); r.throws_a(); } catch (a) { r.release(); // oops; null pointer some times } catch (b) { try { r.release(); } catch (a) { // nooo.... } } finally { if r != null { r.finalize() // use after release (sometimes) r.release() // ??? } } There is plenty of academic literature sh…

> r.release(); // oops; null pointer some times

Quite sure Java would prevent that if r was never assigned.

Also most languages provide cleaner try-with-resources or RAII style lifetime management so you don't actually end up with that kind of spaghetti code unless you actively go out of your way to be bad at programming.

Post reply on HN