You can't compare it to Java checked exceptions. Java checked exceptions are one of those billion dollar "mistakes". It is the single worst thing in Java for me. Checked exceptions add nothing and break almost everything around clean design & code.
For that comparison to work, java would have needed to only have checked exceptions, with some added language features to deal with them cleanly, and then it might actually have been a viable design. Littering your code with try-catch is what makes exceptions infeasible for error handling.
> It is the single worst thing in Java for me. Checked exceptions add nothing and break almost everything around clean design & code.
Should I compare it to "Golang Dependency Hell Claimed My Project?"
> For that comparison to work, java would have needed to only have checked exceptions, with some added language features to deal with them cleanly, and then it might actually have been a viable design.
Why? That's not what happened with Golang's error handling?
It's not a problem you have to deal with but those of us from the world before bundled vendoring list projects because of Go's creators not having sympathy with people not living in a single global monorepo universe and most of its audience not having the discipline to vendor stuff by hand.
> Should I compare it to "Golang Dependency Hell Claimed My Project?"
Of course you can. But it would be hilarious considering Java Module system (Jigsaw) which took decade in making still does not support versioning. People are left to use bloated crap like Maven or Gradle. But since these products are called "enterprise grade" developers are not supposed to call them crap that they really are.
Ah yes the good 'ol "bloated crap" argument developers love to fall back on when they don't know what they're talking about.
What exactly is "bloated crap" about maven? It works exactly as advertised and a heck of a lot better than go modules/vgo.
If you say XML you lose (it is a config fmt get over yourself...). If you say it downloads the world I suggest you look at the output scroll by on any decent sized project in Go land.
I usually end up writing a bunch of utility methods for stuff like this. Typically it's called something like `parseQuietly`, and it just Pokemons any exceptions.
> Littering your code with try-catch is what makes exceptions infeasible for error handling.
I honestly don't see the big difference between littering your code with if/else blocks versus littering them with try/catch blocks. Can you elaborate?
If/else provides a clear and easy to follow control flow. try/catch is like a roaming goto that works it's way back up your stack in ways you can't predict.
The context here is Java's checked exceptions, which have to be handled explicitly at the site where they may occur, leading to control flow that - in my view - isn't substantially different from handling errors with if/else.
I don't understand the argument that stack unwinding is unpredictable -- the most naive implementation of exceptions would just be multiple-function returns with automatic propagation (effectively the same as automatically putting the try! macro on every call in Rust).
Good exception-based code shouldn't be littered catch blocks; you only need to catch in places where you can reasonably recover. No matter how complex the application, there are typically only a few places you can meaningfully recover from a real exceptional or unexpected error situation.
Checked Exceptions in Java, for example, force you to litter your code with catch blocks and error handling code that doesn't actually recover from the error. It transforms it. It propagates it. Languages like Go with explicit error handling do the same thing. I don't think that's bad in all situations but often it comes down to what one thinks is an unexpected error for a given project.
I thought extending _throws_ with an _as_ clause would make it far more manageable:
void foobar() rethrows IOException as AppException rethrows FooError, BarError as WtfError {
Being able to express that a bunch of internal exceptions should be wrapped in an application exception would save a ton of boilerplate.
The exception syntax itself is also clunky. If you have a complex expression, you have to extract it and assign it to a variable. But you still have to declare that variable outside the try/catch. And, of course, every exception requires Yet Another Class Definition. I'd do:
class SomeClass {
exception ThingBroke handles ArithmeticException;
exception DatabaseDown handles SQLException;
void method(int a) {
try {
int x = (555 / a rethrows ThingBroke) + (getNum() rethrows DbDown);
} catch(ThingBroke e) {
I think the other issue is the separate hierarchy for unchecked exceptions. In theory, they were supposed to be issues you couldn't recover from, thus the correct response was to let the caller fail. But now UncheckedIOException is not a subclass of IOException.
Maybe a better approach would be to add an Unchecked interface, though from my reading of the source for exceptions, they seem to be very brittle and maybe there's just no fixing it.
> Being able to express that a bunch of internal exceptions should be wrapped in an application exception would save a ton of boilerplate.
It would but I think it's the wrong approach -- you're actively changing the error information that really provides no additional value except to make the type-checker happy because the alternative is too verbose.
You no longer propagating the same error; if you were type-checking on network exceptions, for example, you would entirely miss it if it was wrapped in LibraryException instead.
Wrapping does have value if you are really adding useful information but the example here is just changing the type which really doesn't add anything useful.
Java checked exceptions were copied from CLU, Modula-3 and C++, even though Java's somehow made them famous.
And even C++, after dropping exception specifications in C++17, might get a simplified version back in C++23 as part of value based exceptions proposal.
The irony there is that Result<T,E> is entirely equivalent to "checked" exception specifications. The quality of surrounding support to "deal with [error states] cleanly" in one vs. the other makes all the difference.
For that comparison to work, java would have needed to only have checked exceptions, with some added language features to deal with them cleanly, and then it might actually have been a viable design. Littering your code with try-catch is what makes exceptions infeasible for error handling.