Dunno, try/catch is a perfectly valid way to entrap known or unknown errors/throws as thats essentially its entire purpose. I think this post just shows a lack of creativity from the individual in that he's essentially just recreating what try/catch already provides by default. You can have try/catch blocks catch any error, test for errors you're aware about, then re-throw errors that you don't know about yet or that this code block doesn't care about. In-fact, I think thats a general agreed upon approach toward error handling. His approach reminds me more of subroutine error handling which can get unmanageable fast due to lack of context for the error.
I usually don't check for them, which is a bad habit on my part. When I do, I throw descriptive strings, and allow them to crash the program; effectively the assert model. If the uncaught string exception isn't already output at runtime, I'll make a single top-level try/catch that will dump the error string and then quit the program.
Anything not worth crashing the program over is just added to an error log or otherwise displayed on screen without throwing an exception. I can't think of any case outside of a classroom where I found it useful to catch and continue after an exception is thrown.
I'm among those aesthetically offended by the presence of try/catch constructions in my code. With that said, I think there's a good functional argument for throwing exceptions rather than returning null for functions called with bad parameters (or otherwise operating on unacceptable data), since forgetting to check for null will give a more obtuse error message than forgetting to catch an exception.
The post seemed lightweight, I mean does he really want that parse function to return 'null' without any indication what the problem is ? That sounds like bad news for solving problems with parsing complex strings.
For my latest projects I eschew error handling, it soils my beautiful code. If I have a weird bug I will put try/catch and remove it again after it is solved.
Regardless of whether you write your code in a 'return value' or 'try/catch' mindset, you still have to handle the result - whether it's an exception or an error code.
There's logic that must be put into place to differentiate between application-ending errors / throws and return codes, and I honestly don't see him making any reasonable case why one is better than the other.
Hey Andrew. Sorry to ask about something unrelated here, but I couldn't find your email address.
You once linked to a 7 day roguelike in which if you died, you started playing as a different charcter in the game world. I tried looking for it but I can't find it. Can you tell me its title again please? Thanks in advance.
Inside of the actual game logic I just let the exception crash the game, because it means there is some edge case I did not handle. After that the game state is invalid anyway.
Now in the platform specific code (where errors can be caught and responded to) I use the standard try/catch approach.
I mainly develop in dynamic languages, and feel this style of coding works well. You just need to be sure and write good tests to get all the edge cases.
I think the argument is flawed in its beginning: who ever said you can't do both?!
I validate input via validation a return codes, and deal with unexpected and programming mishaps via throw/catch.
If I get passed an invalid data file (say a map or profile or DBlink), I don't know what caused the error: user input? corrupted inifile? security? I might be 3 stacklevels down in my library, and the error might be caused by the original caller. So I throw and let whomever did the actual call find out where the problem is exactly. Doing otherwise means having to treat return codes in every part of my code that can have the problem, where it will never be called in a sane environment.
OTOH, when I'm validating input I return codes. When I process something that can fail even when the programmer hasn't done anything wrong, that's a return code job. Using exceptions is just wasting firepower.
Exceptions are... exceptions. Should not be used as a mean to deal with everyday's runtime errors, but with ...exceptional (;) I know...) situations. Not expected situations. failing to open the file the user typed in is for error codes to deal with. Failing to instance a class you've been passed on by Class object is an exceptional case and should be dealt with via throw/catch.
Doing it the other way around is unnecessary in the first case and problematic in the second.
Example: SecurityOptions prevent me from reading resources? That's a throw/catch error. I need to catch it at the top level so it can be reported to the user in the best way, and no other part of the software needs to know.
Dunno, try/catch is a perfectly valid way to entrap known or unknown errors/throws as thats essentially its entire purpose. I think this post just shows a lack of creativity from the individual in that he's essentially just recreating what try/catch already provides by default. You can have try/catch blocks catch any error, test for errors you're aware about, then re-throw errors that you don't know about yet or that this code block doesn't care about. In-fact, I think thats a general agreed upon approach toward error handling. His approach reminds me more of subroutine error handling which can get unmanageable fast due to lack of context for the error.
ReplyDeleteI usually don't check for them, which is a bad habit on my part. When I do, I throw descriptive strings, and allow them to crash the program; effectively the assert model. If the uncaught string exception isn't already output at runtime, I'll make a single top-level try/catch that will dump the error string and then quit the program.
ReplyDeleteAnything not worth crashing the program over is just added to an error log or otherwise displayed on screen without throwing an exception. I can't think of any case outside of a classroom where I found it useful to catch and continue after an exception is thrown.
I'm among those aesthetically offended by the presence of try/catch constructions in my code. With that said, I think there's a good functional argument for throwing exceptions rather than returning null for functions called with bad parameters (or otherwise operating on unacceptable data), since forgetting to check for null will give a more obtuse error message than forgetting to catch an exception.
Greetings,
ReplyDeleteThe post seemed lightweight, I mean does he really want that parse function to return 'null' without any indication what the problem is ? That sounds like bad news for solving problems with parsing complex strings.
For my latest projects I eschew error handling, it soils my beautiful code. If I have a weird bug I will put try/catch and remove it again after it is solved.
T.
Regardless of whether you write your code in a 'return value' or 'try/catch' mindset, you still have to handle the result - whether it's an exception or an error code.
ReplyDeleteThere's logic that must be put into place to differentiate between application-ending errors / throws and return codes, and I honestly don't see him making any reasonable case why one is better than the other.
I'm missing the option "let it core dump".
ReplyDeleteHey Andrew. Sorry to ask about something unrelated here, but I couldn't find your email address.
ReplyDeleteYou once linked to a 7 day roguelike in which if you died, you started playing as a different charcter in the game world. I tried looking for it but I can't find it. Can you tell me its title again please? Thanks in advance.
Generally speaking, my defaults are:
ReplyDeleteC#/Java: try/catch
C/C++: asserts and sometimes logging
Ori: You only live once, by Jeff Lait.
ReplyDeleteInside of the actual game logic I just let the exception crash the game, because it means there is some edge case I did not handle. After that the game state is invalid anyway.
ReplyDeleteNow in the platform specific code (where errors can be caught and responded to) I use the standard try/catch approach.
I mainly develop in dynamic languages, and feel this style of coding works well. You just need to be sure and write good tests to get all the edge cases.
I think the argument is flawed in its beginning: who ever said you can't do both?!
ReplyDeleteI validate input via validation a return codes, and deal with unexpected and programming mishaps via throw/catch.
If I get passed an invalid data file (say a map or profile or DBlink), I don't know what caused the error: user input? corrupted inifile? security? I might be 3 stacklevels down in my library, and the error might be caused by the original caller. So I throw and let whomever did the actual call find out where the problem is exactly. Doing otherwise means having to treat return codes in every part of my code that can have the problem, where it will never be called in a sane environment.
OTOH, when I'm validating input I return codes. When I process something that can fail even when the programmer hasn't done anything wrong, that's a return code job. Using exceptions is just wasting firepower.
Exceptions are... exceptions. Should not be used as a mean to deal with everyday's runtime errors, but with ...exceptional (;) I know...) situations. Not expected situations. failing to open the file the user typed in is for error codes to deal with. Failing to instance a class you've been passed on by Class object is an exceptional case and should be dealt with via throw/catch.
Doing it the other way around is unnecessary in the first case and problematic in the second.
Example: SecurityOptions prevent me from reading resources? That's a throw/catch error. I need to catch it at the top level so it can be reported to the user in the best way, and no other part of the software needs to know.
My .02.