8 ms·
The trouble with Checked Exceptions (C# architect)
- kbd 14y agoFor old articles, please put a date in the title. In this case, (2003).
- AndrewDucker 14y agoIf it was something that was time-dependent, I'd agree, but in the case of an interview talking about the design of two languages in current use,it's timeless.
- sirclueless 14y agoThat's all the more reason to put the date there. It signals an article that is relevant today despite being almost ten years old. The argument is considerably more impressive when you realize that it happened ten years ago and is still relevant, but I didn't know it was a timeless classic until I saw this comment thread.
- rvkennedy 14y agoI have long wondered about the syntax of exceptions - if it was: void function() { try: function_body... catch(Exception e): finally: } By leaving the function body in the same indentation as it would be without exception handling, this might help to make the code a little more readable than: void function() { try { function_body... } catch(Exception e) { } finally { } }
- AndrewDucker 14y agoThat would be useful if you only need a try/catch at method level. If you need two try/catch chunks in a method then that wouldn't work. I do agree that having try/catch at method level would be useful in many ways - as an additional piece of syntax.
- ajitk 14y agoMy mind parsed the first code block as a mix of Python and C. IMO, the later would be more readable since it involves parsing only one rule that the eye is already used.
- udp 14y agoIt reminds me more of C, where labels and goto are often used for error handling (labels using the same `:` syntax).
- ajitk 14y agoNow that you you mention labels, I see the similarity to C. I might have been influenced by OP's reference to use indentation to make code more readable instead of using braces.
- gioele 14y agoThe crux of the question: > Bill Venners: But aren't you breaking their code in that case anyway, even in a language without checked exceptions? If the new version of foo is going to throw a new exception that clients should think about handling, isn't their code broken just by the fact that they didn't expect that exception when they wrote the code? > Anders Hejlsberg: No, because in a lot of cases, people don't care. They're not going to handle any of these exceptions. There's a bottom level exception handler around their message loop. That handler is just going to bring up a dialog that says what went wrong and continue. The programmers protect their code by writing try finally's everywhere, so they'll back out correctly if an exception occurs, but they're not actually interested in handling the exceptions. > The throws clause, at least the way it's implemented in Java, doesn't necessarily force you to handle the exceptions, but if you don't handle them, it forces you to acknowledge precisely which exceptions might pass through. It requires you to either catch declared exceptions or put them in your own throws clause. To work around this requirement, people do ridiculous things. For example, they decorate every method with, "throws Exception." That just completely defeats the feature, and you just made the programmer write more gobbledy gunk. That doesn't help anybody.
- ams6110 14y agoI'm in Hejlsberg's camp on this. Exceptions should rarely be handled. If a non-happy-path use case causes exceptions, you're doing it wrong: exceptions should not drive your program logic; you should be proactively checking or guarding for those conditions. Exceptions are for things you didn't foresee, and ergo are not anything you're going to be able to "handle" other than by bailing out as cleanly as possible.
- paol 14y agoExactly. I think the 2 key failings of the checked exception idea (there are others, but not as important) are 1) Precise exception specifications leak implementation details. This will bite you badly, e.g., when you want to change the implementation from under a published API. 2) The times when we only care that some exception occurred vastly outnumber the times when we care about the exact types of exceptions that may occur. Checked exceptions don't add any value to the common case, in fact they make it worse, because generic exception handlers tend to live many levels up the call stack from where exceptions are thrown(1), and therefore they "aggregate" large amounts of code that that can collectively throw a huge range of exceptions. If you were to carry around detailed "throws" clauses, they would be a mile long. The funny thing is, all solutions that solve the problems created by checked exceptions do so by subverting the mechanism one way or another. So you're better off without checked exceptions in the first place. I've always been interested in this discussion because it's one of those cases where an idea seems very good on paper, only to turn out quite bad in practice. (1) This observation is what makes exceptions such a useful mechanism in the first place.
- AndrewDucker 14y agoI am _very_ glad that C# does not have checked exceptions. Anders is completely correct in that the vast majority of the time individual methods do not handle specific exceptions, they just roll things back and pass the exception up the way. Adding exception attributes in all of these places would be a massive pain.
- TazeTSchnitzel 14y agoThe reality is that programmers do not have the time to handle every single possible exception. I reckon every few function calls you make could potentially trigger an exception. You generally just have a catchall (or not, and let the program abort), and then catch certain specific exceptions that are common enough.
- AndrewDucker 14y agoAbsolutely. I handle the ones that are common enough to be worth investing time in (or have severe enough consequences). The rest recover as best they can and tell the user "Something bad happened. Call the helpdesk." (while logging a stacktrace).
- freeman478 14y agoYes unchecked exceptions are nice. However it would be nice if the compiler could enforce documentation of possible exceptions raised by a method. Something like the throws keyword of Java with unchecked exceptions. That way you (through the IDE) could know at any point of your code what exceptions could happen (and not have to guess or go through all the called code to identify them).
- nknight 14y ago> I reckon every few function calls you make could potentially trigger an exception. One Java module I had the misfortune of writing theoretically had to deal with checked exceptions on the majority of its calls, and the only possible response to virtually all of them was to crash, because in that context, it could only have meant someone had either ripped the DRAM off the board, or placed the board in a particle accelerator.
- philf 14y ago> You end up having to declare 40 exceptions that you might throw. And once you aggregate that with another subsystem you've got 80 exceptions in your throws clause. It just balloons out of control. What he completely ignores is the possibility to wrap exceptions to either aggregate them or to convert them into unchecked exceptions.
- thebluesky 14y agoExactly. I've been using Java for 13 years and have yet to see a method signature with more than a handful of exception types thrown, let alone 40 or 80. I've told you a millions times not to exaggerate ;)
- je42 14y agoThanks ! I just thought i was missing somehting , that Heisenberg did not mention exception wrapping. The funny thing about that technique is, that a lot of people do know it, they ususlly just print a strack trace and ignore the exception...
- henrikschroder 14y agoI sense some uncertainty on how to spell his name...
- je42 14y agooops sorry for the typo ;)
- paol 14y agoBut that's exactly one of the main points of the detractors of checked exceptions (of which I'm one): the only sane way of working with it is to subvert it. Whether you convert the throws clause to a common supertype (which very soon converges to the base type Exception), or wrap everything in a RuntimeException, you are effectively emulating a language without checked exceptions. So what was the point in the first place?
- philbarr 14y agoAs a long time Java programmer, who has been writing C# for the last year and a half, I think leaving out checked exceptions from C# may have been a bad idea. What they've done is to identify that checked exceptions are a pain in many cases and simply removed them without providing a proper replacement. This particular quote demonstrates what I mean: "To work around [the need to declare what you intend to do with each exception] people do ridiculous things. For example, they decorate every method with, "throws Exception." That just completely defeats the feature, and you just made the programmer write more gobbledy gunk. That doesn't help anybody." Ok, so what you did instead was to effectively put "throws Exception" on every method by default. You actually implemented the workaround you've just criticised into the language? And what's the effect of this - whenever you call a method in an API, you have no idea what could go wrong with it, so you can't write code to handle it. It wouldn't be so bad if a method's potential exceptions were documented, but they never are. So you end up in a situation where you just code for the simple "happy case", run it, see what breaks, put some exception handling in (for just Exception) where you can, run it again, etc. It's a dreadful way to write code. I'm not saying Java's checked exceptions were great - far from it - but C#'s "solution" is terrible. The number of times you end up with a NullException because some method failed somewhere deep in your code and something else didn't get initialised is unreal. If you don't believe me, try working with Sharepoint for a few minutes, and that's Microsoft code. [edit - spelling]
- pohl 14y agoOk, so what you did instead was to effectively put "throws Exception" on every method by default. That implicit throws clause was already there in any language that contains unchecked exceptions for things like dereferencing a null pointer, or assertions, etc. So, no, that's not what removing checked exceptions does. Personally, I'm a big fan of Guava's Throwables class. The java I write these days transmutes all checked exceptions into unchecked wrappers at any API boundary that tries to force them on me. And, no, this doesn't mean I'm only coding for the happy case. Rather, I'm choosing where and how to handle the sadness.
- lsd5you 14y agoIt depends what standards you hold the library to. Null pointer exceptions and other runtime exceptions are can be treated as errors - something which needs fixing in the code, rather than something that can be handled. A world of difference.
- Uchikoma 14y agoChecked exceptions are fine. The problem is, that they are not composable and most languages have no syntactic sugar for dealing with them as Monads. Other checked error mechanisms like Either or are much easier to manage. I do hope e.g. Java sometimes in the future gets syntactic sugar to deal with checked exceptions as Monads.
- lenkite 14y agoThe Java Programming Language's checked exception feature is fundamentally broken. All newer Java specifications have acknowledged this and utilize un-checked exceptions.
- tomjen3 14y agoAll but one (and arguably the most important) Android. Android is full of brand new checked exceptions. And I do what I always do with checked exceptions: catch (e) { throw new RuntimeExeception(e); } (you can't keep adding throws clauses because the compiler won't let you add them if the interface you implement can't handle them).
- dscrd 14y agoExceptions are a bad idea. Even in the more saner languages such as python, they tend to obfuscate needlessly.
- je42 14y agoso you prefer to decentralize your exception handling code ? how do you scale that ?
- dscrd 14y agoThe problem is that when exceptions are available, people will start using them for non-exceptional things and (the worst case) basic control flow. Case in point from a popular framework, Django: the standard way of getting an object from the DB via the ORM is Class.objects.get. This method either returns a single object or raises on exception if there are zero rows in the db or another exception if there are two or more rows. It may also raise other kinds of exceptions. Now, it's clear that having zero rows is not very exceptional, and even >1 is somewhat debatable. Note especially that this is not just some weekend project by a nobody, it is a framework that is widely used and respected.
- Ingaz 14y ago>> and (the worst case) basic control flow. I call it "java-way goto" I can't agree about Class.objects.get - method must return exactly one row by known pk value. So it perfectly sane to raise exception for zero rows. Class.objects.filter is working the way you want.
- dscrd 14y agoExcept that get accepts as parameters non-unique non-primary fields too. I have every reason to believe that the Django devs are capable people who thought about this and landed on this specific usage with a clear rationale... but it still is a misuse of error handling capabilities of a language. And a sort of misuse that everyone else does sometimes as well.
- 14y ago
- viraptor 14y agoThe thing that really annoys me about checked exceptions is that map/reduce/fold like functions throw anything by definition. Basically as soon as you allow any general type function as a parameter, you need to mark yourself as throwing everything. That is really limiting in some scenarios.
- ZitchDog 14y agoI have thought quite a bit about checked vs unchecked exceptions and come to the realization that there is a fundamental philosophical problem that checked exceptions can never overcome. The idea with checked exceptions are that they should be used for errors which the caller should be forced to handle. But this property is entirely dependent on the context the function is being called from! For example, if the user is specifying a filename for a file, I should be expected to catch the error and display feedback to the user. However, if I just wrote the file to disk 5 seconds ago, I shouldn't be forced to trap the error! The crux of the problem is this: the severity and recoverability of an error is known only by the caller of the function, not the function itself. Checked exceptions attempt to foist this information into the function itself, where it is unknowable and generally inaccurate. Checked exceptions are a misfeature if I ever saw one.
- scott_s 14y agoI agree with the C# designers' reason that checked exceptions are not a good idea, but I don't agree with yours. In other words, your argument is different than theirs, and I don't agree with it. (Although I still agree with your conclusion.) The crux of the problem is this: the severity and recoverability of an error is known only by the caller of the function, not the function itself. I agree with that statement, but not that it is the crux of the problem with checked exceptions. That statement is an argument for general error reporting - it need not even be exceptions. Simply, the function that encountered the error does not know what to do about it, so it must report it on up the stack. We could just as easily accomplish that with error return values - I'm not saying we should, just that I think your argument is too generic to support your conclusion. Checked exceptions attempt to foist this information into the function itself, where it is unknowable and generally inaccurate. And that I actually disagree with. Checked exceptions require that the calling function acknowledge that an error has occurred, it does not require the calling function to handle the error. The calling function could easily catch the exception and rethrow it, or just add the exception to its own throws clause. The C# designers' argument is that what I described is generally what people want to do, so why not just make it the default? That default is unchecked exceptions.
- 14y ago
- bokchoi 14y agoI tend to agree that Java's checked exceptions are annoying (hello SQLException). However, when I used C# I was annoyed that the VS intellisense and the C# generated documentation didn't tell me what exceptions might actually be thrown! In practice this meant just not handling anything at all.
- darrenkopp 14y agoThat's because the developer didn't put the exception into the documentation. But at the same time you really shouldn't rely on that because something down the line could throw an exception that isn't covered in the documented exceptions.