8 ms·
I like checked exceptions. Yes, sometimes (especially in the oldest APIs when they were still figuring this stuff out), they were overused but mostly I think th
by alasdair_ 6y ago
I like checked exceptions. Yes, sometimes (especially in the oldest APIs when they were still figuring this stuff out), they were overused but mostly I think they encourage developers to really think about what happens in the failure case.
I notice this especially with less experienced developers and remote calls - a lot of JS code I’ve reviewed in the past assumes the remote call will always work, yet Java code from the same developer will almost always correctly handle the situation, simply because the exception is explicitly required to be handled.
- Deadron 6y agoOne of the bigger problems is that exceptions are slow. Thus the recommendation is not to use them in cases where the caller could branch on. A perfect example is a missing element in a remote system. An old api would throw some sort of a Element Not Found Exception. With the addition of Optional though you have a object that is easier to use, conveys your intention better, and doesn't have any of the performance drawbacks. I think what it comes down to is that when dealing with situations that might be handled by the caller you should use some sort of result object instead of a exception. This leaves exceptions only for the cases where the result cant be handled. In which case you dont need checked exceptions.
- josefx 6y ago> A perfect example is a missing element in a remote system. An old api would throw some sort of a Element Not Found Exception. Wait, if the example involves a remote system how can the Exception be the bottleneck? Even generating the completely optional stacktrace shouldn't take that much time.
- benjiweber 6y agoNot as slow as many people think, especially with things like OmitStackTraceInFastThrow
- sreque 6y agoOmitStackTraceInFastThrow has caused so many headaches in debugging production issues, and each time now the answer has been to just disable it. The real answer is to stop trying to abuse exceptions as a form of general control flow.
- josefx 6y agoFor some reason the most talked about "alternative" to exceptions seems to be "use optional". I would assume that this has the same debug issues as omitting the stack trace.
- dllthomas 6y ago> I would assume that this has the same debug issues as omitting the stack trace. I don't expect so. If I "forget to handle" an optional, I get an error at compile time pointing at the lines in question. If I forget to handle an exception with an omitted stack trace, IIUC, I am told at runtime that there's an error somewhere in my program. It's much easier to debug the former.
- thu2111 6y agoExceptions are slow to throw, but they're meant to be exceptional so that's OK. Good implementations impose no overhead the rest of the time. This is not the case for return type based systems, where you can easily end up with an allocation that must be GCd later.
- AlexTWithBeard 6y ago> hey encourage developers to really think about what happens in the failure case. It's a noble goal, but once I started thinking about what happens in the failure case, I came to the conclusion that checked exceptions are no help here: - there are always unchecked exceptions. I found it useful to think that any function might throw. So if extra reporting or graceful shutdown are required, just catch everything - in most cases I have no idea how to recover from error: just keep throwing it to the caller until someone knows what to do. I want it to be the default behavior and I don't want to clutter my code with all the catch-wrap-rethrow boilerplate.
- hota_mazi 6y ago> in most cases I have no idea how to recover from error: just keep throwing it to the caller until someone knows what to do. I want it to be the default behavior and I don't want to clutter my code with all the catch-wrap-rethrow boilerplate. What's your alternative? Using return values? But then you are doing the bubbling, manually. Exceptions offer a more elegant and less boiler plate approach to this problem: if your code can't handle an exception, just declare it in your signature and ignore it. This is really the best approach to this problem: - The error cases are part of the function's signature (as they should). - The language takes care of bringing the exception to the right handler. - Your code can proceed with the assumption that all the values are sound.
- aeternum 6y agoI've found that in practice it leads to very generic exception names. When a new failure mode is found for a lowlevel component, in other languages devs would add a new specific exception and things would generally work. In Java, devs have to modify every intermediate component to handle or pass the new exception type so they end up just using an existing one that is super generic.
- 0xffff2 6y ago>What's your alternative? Using return values? But then you are doing the bubbling, manually. Huh? The alternative is unchecked exceptions, which are already present in Java and therefore have to be accounted for anyway. Removing checked exceptions from Java would greatly simplify the APIs that use them, with absolutely zero cost.
- hota_mazi 6y agoRight. They don't just "encourage" developers to consider error paths, they "force" them to do so. The concept of checked exceptions is very sound, as is the more general concept of compiler enforced error checking. Very, very few languages have that (only Java and Kotlin in the mainstream league). Languages with a solid implementation of algebraic data types offer a good first step in that direction but they still require users to manually bubble and compose monadic values, which introduces an unnecessary, and sometimes intractable, level of obfuscation and boiler plate. All other languages provide weaker approaches to this concept that are library enforced, not language enforced, and therefore more prone to being overlooked since they require discipline from the developer.
- augusto-moura 6y agoYou are not forced per se, and can have the same level of obsfucation. It's pretty common to find code ignoring exceptions or wrapping them in RuntimeExceptions, like: try {} catch (Exception e) { throw new RuntimeException(e); } Also not doing nothing, or the famous catch and log
- mcguire 6y agoOnce upon a time, I worked on a C++ project with another, experienced developer who kept commenting out -Wall from the Makefiles with the comment, "Nobody has time for that."
- staticassertion 6y agoYou aren't forced to handle it well, you are forced to handle it.
- Groxx 6y agoI tend to also point out in a lot of these discussions that "checked exceptions" and "java's implementation of checked exceptions" are different things. Java's implementation has undeniable issues, e.g. in designing stuff with callbacks. It can and often does lead to "everything's runtime" or "everything throws Exception" or other hell-scapes people have heard of. Personally I still prefer them, for pretty much the same reason you mentioned - they are effective, especially with a bit of restraint. Checked exceptions as a concept are not bound to that. And I wish more languages would make use of them. They can be just as flexible as ADTs, which are pretty widely approved of... because they describe exactly the same thing, just short-circuiting rather than requiring an explicit return. On that front, it's "exceptions" vs "returns" and there are plenty of opinions and tradeoffs between them.
- sreque 6y agoPerhaps because the complexity budget of trying to get checked exceptions right is so high that no one even bothers to try. Once you find yourself able to just return values representing an ADT, then why bother? If the point of a checked exception is that the caller should try handling it immediately, then just return a value like IO<T> instead of return T but maybe throw IOException.
- ragnese 6y agoBut Java has no language support for dealing with a Try/Result type. It would be objectively worse than just using checked exceptions, IMO.
- sreque 6y agoIt's definitely not ideal, but I use Optional to replace nulls in Java and I think it works fine. Similarly you can return values that could represent an error. Or, you can throw an unchecked exception. Callers should be aware of all exceptions a method can throw, especially since those can include unchecked exceptions the compiler doesn't tell you about. Since the caller should do this work anyways, using unchecked exceptions is more than acceptable.
- flukus 6y ago> I like checked exceptions. Yes, sometimes (especially in the oldest APIs when they were still figuring this stuff out), they were overused but mostly I think they encourage developers to really think about what happens in the failure case. I agree and like them in theory, but in practice the only practical thing that can be done with an exception is to get away from this section of code as quickly as possible and get back up to a layer where the user/system can be notified of the failure in some way. Cases where you actually can gracefully handle an exception like a missing file tend to be something you should check and not rely on exceptions for anyway.