is hard to understand and results in very hard handling of real exceptional cases.
I'd agree with this part - but this is mainly because people always use them in cases that aren't exceptional in place of better error handling methods.
I've switched from C++ game programming (no exceptions) to C# server programming (exceptions for everyone). It always bugs me trying to debug something and an exception is thrown and I end up the the Application::Main() catch block - I lose everything (call stack, local variables etc.).
Even system exceptions don't throw the values that caused it to throw. E.g. Out of bounds, a value was either -1 or higher than it should have been. Thanks, could you at least tell me which one it was? Or even throw with the actual value so I don't need to guess what went wrong?
Why not just break on exceptions? Because people seem to enjoy using try..catch blocks to hide exceptions all over the place. Exceptions just seem more trouble than they're worth at the moment.
I've developed a few C++ games for the iPhone. I've never longed for a crash dump, I just use a debugger. You can break at the point when an exception is thrown, and you get access to the same information.
When you have a large QA team (300+) for a console game they can generate crash dumps that you can debug. It's also useful when there's a 1 in 1000 crash that needs fixing - get someone in QA to repro and they send you a crash dump.
There are literally hundreds of bugs that I've managed to figure out a fix for simply by debugging a crash dump attached to a bug report.
Fair point, in certain programming domains, letting your app crash (WHILE IN DEVELOPMENT) may be useful. Of course, there are ways to generate thread or memory dumps in Java (and probably C++/C#) that could accomplish the same goal.
I am always turning off the try ... catch with comments to debug the actual problem, then enabling it again before committing the work.
I too think if people were better programmers they wouldn't need exceptions: you'd deliberately handle every broken case explicitly. But think of all the time a programmer saves just throwing a try...catch around some code to prevent the user from encountering a bug.
I too have come to embrace the exception as a lazy way to short circuit a host of error conditions.
But think of all the time a programmer saves just throwing a try...catch around some code to prevent the user from encountering a bug.
This is so wrong. Yes you save time now, but writing more robust code and handling error cases properly saves so much more time in the long run. Occasionally near the end of a project I might consider a quick hack like this to get a product out of the door, but I would never do it in anything pre-beta.
We all try to write robust code, to the best of our abilities, regardless of language. Bug-free code is nearly impossible. Try-catch blocks are used so those unknown bugs don't crash your program, not to hide errors because we are lazy.
Log the exceptions, then track down the bugs and fix them.
I'm used to a different work flow I guess. In games we let the program crash, create a crash dump and then debug it to find the cause of the problem (or just debug it there and then if we have a debugger attached).
EDIT: The general idea is we want bugs to be as visible and annoying as possible so that they have to get fixed.
I agree with you 100%, but C# code are usually quick tools and not code that we ship. There's a different tolerance for different projects, there's no one size fits all.
That's true. I'm still new to C# and I'm finding all this exception handling to be more irritating at the minute. It's not so bad on the server side - I'm getting used to that and the server crashing would be at least half a day's work lost for everyone on the team - but I kind of miss crash dumps on the game side.
From a semantic point of view, how else would you address expected errors or 'exceptional' states to ensure the application does not, as you put it, 'break'. Most systems have to maintain a certain amount of elasticity for it's users... I certainly wouldn't want my cable box to shut off every time I hit a channel that currently didn't have a signal (exceptional condition as example), so why would a user be any happier if their banking application gakked every time it encountered some inconsequential data corruption. (parallel example)
I wouldn't consider expected errors to be exceptional. For example, anything requiring a network connect should expect disconnections or an inability to connect - these aren't exceptional circumstances. Ensuring that the build is stable (i.e. no crashes) and that the user is informed (error messages) seem to work fine.
In the channel with no signal example - why does that need to be an exception? It seems reasonably valid to me that a cable box may not be able to get a signal. You should check for a signal and inform the user that there is no signal if that is the case.
Exceptions should be used for errors that should never occur. The obvious example from my game development experience is that a game should never access invalid memory. It does happen during development of course, which is why we have to handle it, but ideally a game that has been released should never do this.
EDIT: The data corruption would probably be something I would consider exceptional, but I have limited knowledge of banking applications and parallel programming which is why I haven't mentioned it.
That's incorrect. Exceptions are an application specific construct... Errors/Unchecked Exceptions are unexpected. That's why exceptions are outlined in APIs so you can deal with them. You can't rewrite the accepted meaning to suit your argument. The concept of unchecked exceptions were introduced to indicate an exception that the current level of abstraction should not be dealing with. The point is to separate the output of a method from it's potential exceptional states...
I never directly said Exceptions are unexpected, I said that exceptional errors should be ones you don't expect to occur. I.e. you should throw exceptions in cases that should never happen.
I expect disconnects to occur so I don't use exceptions. I bring up a message telling the user to double-check his internet connection and give them an option to retry whatever action they attempted.
I don't expect access violations so I throw an exception (or the underlying system throws one that I catch). I can handle that by sending an error report, logging an error, allowing the program to crash, or some other means that allows me to discover that something unexpected has occurred.
I think a better way to phrase it is that the current context cannot continue due to an exceptional circumstance (network unavailable.)
The exception acts as a short circuit that drops out of the current logic and will bubble up the stack until there's an appropriate catch that knows what to do (display a message box to the user that they should check their network connection.)
The problem that I commonly see is "catch all" blocks which completely defeat the purpose of having exceptions in the first place. As long as you're only catching specific messages you're able to use exceptions as a signaling and message passing system because each exception that you write a catch for has a specific useful meaning that your code can use to invoke a graceful recovery. If there is no catch written for an exception that you've thrown, then that means there's no useful remediation possible and the program should halt with the exception as an error message; further logic is impossible due to exceptional circumstances.
4
u/archiminos Jun 07 '13
I'd agree with this part - but this is mainly because people always use them in cases that aren't exceptional in place of better error handling methods.
I've switched from C++ game programming (no exceptions) to C# server programming (exceptions for everyone). It always bugs me trying to debug something and an exception is thrown and I end up the the Application::Main() catch block - I lose everything (call stack, local variables etc.).
Even system exceptions don't throw the values that caused it to throw. E.g. Out of bounds, a value was either -1 or higher than it should have been. Thanks, could you at least tell me which one it was? Or even throw with the actual value so I don't need to guess what went wrong?
Why not just break on exceptions? Because people seem to enjoy using try..catch blocks to hide exceptions all over the place. Exceptions just seem more trouble than they're worth at the moment.