4 ms·
I do have a problem with (1) checked exceptions, and (2) catching exceptions prematurely and (3) people not learning how to use "finally" so they do (2) and ret
by Lagged2Death 15y ago
I do have a problem with (1) checked exceptions, and (2) catching exceptions prematurely and (3) people not learning how to use "finally" so they do (2) and rethrow.
I am probably one of those people who catches exceptions prematurely and who hasn't learned to use "finally." If you link to some advice on how to use such things, I'll read it. I want to believe that I can learn a better way to use exceptions, but they just haven't clicked for me.
Then again, I've been using exceptions in an environment (C#) that matches the author's JSON.parse() example very well. The .NET library designers already decided what counts as exceptional, and it's often not possible for me, as a .NET user, to decide much of anything about the use or placement of try/catch.
...when you're building real systems, the complexity of the error handling can approach or exceed the complexity of the "normal" path...
I can understand all too well that a complex error handling path is intimidating, tedious, distasteful, and no fun at all. But in every serious project I've been a part of, error and exception handling has been where the bulk of the design, implementation, and testing work was done. That stuff is precisely how serious systems distinguish themselves from toys. Having a catch-all crash-path doesn't change that, because the serious system is not permitted to crash. As the author here points out, that's what assert() has offered for decades anyway.
- dpark 15y ago>The .NET library designers already decided what counts as exceptional, and it's often not possible for me, as a .NET user, to decide much of anything about the use or placement of try/catch. What do you mean? You can certainly decide what's exceptional. You can roll your own exceptions. You can catch and discard or handle exceptions you don't want to bubble up. You can put try-catch everywhere or nowhere (or choose a reasonable place in between). Your hands are not tied by .net exceptions any more than they are tied by any other reasonable error handling model.
- Lagged2Death 15y agoYou can certainly decide what's exceptional. I can decide to make something in my code exceptional, sure. I can't decide to make something in the library not-exceptional, though. You can put try-catch everywhere or nowhere (or choose a reasonable place in between). This isn't always the case. Sometimes the only way to answer a question ("Can this string be parsed as an integer?") is to try it and catch the exception. And there's just no way to do that coherently without catching it immediately. Later releases of .NET do include a non-exception-throwing TryParse() call in many places. I'm pretty sure I've run into some cases where that was not available, however, and I'm pretty sure I've run into similar situations in other methods besides Parse(). And TryParse() was a late addition; look back in the 1.1 or 2.0 docs, and it doesn't exist. In other words, somebody thought it was reasonable to force .NET users to catch some exceptions immediately. Your hands are not tied by .net exceptions... No, but there's not much point in using .NET if I'm not using the library that comes with it. And the design of the library does tie my hands in some cases. I think the author makes a great point about libraries that use exception handling blurring the line between bugs and expected problems. That's exactly how I feel about the C# work I've done.
- dpark 15y ago> I can decide to make something in my code exceptional, sure. I can't decide to make something in the library not-exceptional, though. Making something in the library non-exceptional is equivalent to discarding an error. Catch the exception and discard it. Done. Do this at whatever level you feel is appropriate (or don't, and handle the exception in a more reasonable fashion). > In other words, somebody thought it was reasonable to force .NET users to catch some exceptions immediately. What do you suppose should be done? The other option seems to be to continue in a erroneous state. I'm probably not familiar with every possible error-handling methodology, but it seems the main ones are "error codes" (those worked so great in C, right), "exceptions" (annoying, but error handling in general is annoying), and "injected handling" (where the caller can inject error handling code somehow; but this is more complicated and requires deeper knowledge about the callee). Is there a better option? > No, but there's not much point in using .NET if I'm not using the library that comes with it. And the design of the library does tie my hands in some cases. My point is that you are not tied by .Net any more than you are tied by any other exception-handling language. You can handle exceptions where and how you feel is appropriate. > I think the author makes a great point about libraries that use exception handling blurring the line between bugs and expected problems. That's exactly how I feel about the C# work I've done. I think this is a bit of a red herring. An exceptional condition is simply a special case. A bug in the code is an exceptional condition. A problem parsing a number is an exceptional condition. Modern languages generally have specific exceptions to allow you to handle different situations with custom logic, but it's important to note that the runtime can't reliably distinguish between "bugs" and "expected problems". Did your number parsing fail because the user entered an invalid value or because your code grabbed column 3 instead of 4?
- Lagged2Death 15y agoMaking something in the library non-exceptional is equivalent to discarding an error ... The other option seems to be to continue in a erroneous state. I guess this is where we differ. I feel that the designers of the .NET library have chosen to throw exceptions in places where nothing exceptional is actually happening, where no error has occurred, where the programmer may very well be expecting the "exceptional" outcome. Where my code must handle such conditions, forcing me to handle them as exceptions makes my code longer, less readable, harder to change, and harder to reason about. ...it's important to note that the runtime can't reliably distinguish between "bugs" and "expected problems". This is exactly what the author of the linked piece points out, this is a part of my complaint, and it's an issue Microsoft has tacitly acknowledged the seriousness of by the addition of alternatives to exception-throwing calls, like TryParse(). The problem from my perspective isn't the runtime or the languages that target it, but choices made when the library was designed. It does not feel to me, as a user of these massive libraries, that there was any systematic way of deciding what should be and what should not be reported as an exception.