5 ms·
> Someone made a change in a function I was calling, and it started throwing a new exception. If it has nothing to do with your code, why not either let it bub
by EMM_386 3y ago
> Someone made a change in a function I was calling, and it started throwing a new exception.
If it has nothing to do with your code, why not either let it bubble up the stack or try/finally it to do whatever clean-up you need to do before re-throwing it and letting it move on to a global logger or similar.
If it is something you care about you can always catch the specific exception type and handle it.
Maybe whoever worked on the other function wasn't even aware it might throw that particular exception.
Granted I am far more experienced in C# than Java, but the idea that with every code change you potentially have to review and declare every single type of exception seems like madness ("what happens if we pull the cord when it's here, what type will that throw?").
- breadwinner 3y agoImagine that the functionality implemented by your method is very important. This functionality should not be needlessly aborted. If so you want to be aware of errors you can recover from, correct? This is why checked exceptions are helpful. It gives you a guaranteed-by-compiler list of exceptions and you can decide which of those you should recover from.
- Akronymus 3y agoThis is one of the main reasons why I personally try to avoid exceptions and instead encode failure into the type system. For example, returning a Result<'t,string> rather than just a 't. (You can refine the type further). Altough, in most languages that approach results in a lot of boilerplate. In F# it works quite well, though.
- necovek 3y agoHow is this different in practice? Checked exceptions are simply "syntactic sugar" for error types (exception objects with a few special handlers to return them and receive them). You can write almost exactly the same code with your Result by ignoring the error until the point you would catch it with exceptions. The only difference is that exceptions bubble up if unhandled, which requires a generic catch to match code ignoring errors otherwise.
- Akronymus 3y ago> How is this different in practice? It is quite a bit more explicit in that something can have an error and in what ways it can error (if you enrich the type in that way), while still being ergonomical. And it reserves exceptions for the truly unexpected/exceptional cases.
- necovek 3y agoAre we comparing the same things? Adding exceptions to the method signature is pretty explicit to me too. It's also pretty ergonomical depending on how you generally treat errors you don't care about. I do find your point about exceptions being for unexpected things interesting: basically, split errors into two classes and use separate mechanisms for each. I generally feel that this differentiation would never hold between different codebases (an HTTP library may consider network error something "normal", but users of that library might consider it exceptional), but it's surely an interesting concept. I also think that we as developers are pretty bad at handling both expected and unexpected errors, so having two mechanisms will only make us less likely to do so (not by much, though). FWIW, my take is that they are largely equivalent except for more or less syntactic support for the approach.
- Akronymus 3y ago> FWIW, my take is that they are largely equivalent except for more or less syntactic support for the approach. Yeah, as with lambda calculus and turing machines, they are equivalent in capacity. > Are we comparing the same things? Adding exceptions to the method signature is pretty explicit to me too. Maybe, maybe not. IME the IDE support for exceptions is quite a bit worse than for returning results and such. > I do find your point about exceptions being for unexpected things interesting: basically, split errors into two classes and use separate mechanisms for each. > I generally feel that this differentiation would never hold between different codebases (an HTTP library may consider network error something "normal", but users of that library might consider it exceptional), but it's surely an interesting concept. Isn't the two ways to handle it already a thing with checked and unchecked exceptions, though? As in having wrappers that convert one to the other. > I also think that we as developers are pretty bad at handling both expected and unexpected errors, so having two mechanisms will only make us less likely to do so (not by much, though). I don't quite agree with that, as with encoding it in the type system conveys more intentionality than with exceptions, IMO.
- wiseowise 3y agoYes. But it’s not as simple as checked=good, unchecked=bad and vice versa.
- throwanem 3y agoOr I can catch any exception out of the codepath I'm concerned about, examine it to see if it's one of the known set of exceptions I intend to handle, and then either do so or rethrow it. If there's a benefit to compile-time exception checking over this method, I have to admit I don't see it. But I've also never worked deeply enough with Java to be familiar with the nuances of its exception handling, so that may be why.
- joexner 3y agoChecked exceptions give you, essentially, syntactic sugar for handling just a few kinds of exceptions and re-throwing the rest. It's useful when there are one or two error cases you want to retry or handle specially, but you want to just barf any other error up the stack. It's a specific use case but it's prevalent. The downside is that sugar can only separate your error conditions by Java type. If everything is just an Exception, you'll have to use sort out your error cases in code.
- throwanem 3y agoBy the sound of it, that's more like syntactic salt, or maybe syntactic thallium - `else { throw error; }` seems much simpler by comparison. Being able to know what exceptions can possibly be thrown at a given point is useful, but seems like a problem better solved through static analysis than by requiring annotations.
- newaccount74 3y agoThe problem is that handling arbitrary errors can be very complex. It's easy to make errors in the error handling code. Especially if the error you are handling never occurs -- because there's no way to test error handling code for an error that never happens. That's why it is really useful to know when a call can fail, and what kinds of errors you have to expect. If you always have to add a generic error handler for possible unknown errors, then you'll write a lot of untested, dead code.
- throwanem 3y ago