Earlier quoted context omitted.
This is a bad idea that keeps coming back again and again. I see nothing wrong with exceptions, 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. Languages like Go and Scala roll out various mechanisms that bring us back to the bad old days of C, when we had to check the return/value and or the error co…
> when we had to check the return/value and or the error code after every function call... if we wanted error handling to work. Errors as return values force you to think about every possible error, which is a good thing for code quality. Look at how much rock stable C software we have out there. Software that can be compiled on many different architectures, run in many different environments, and it all just works,…
Isaacs: try/catch is an anti-pattern
41–50 of 140 posts
Re: Isaacs: try/catch is an anti-pattern
#42Re: Isaacs: try/catch is an anti-pattern
#43Even better, when stack traces in exception logs are examined, it's easy to see where in the call chain things are going wrong.
During a database transaction for example, something might go wrong 5 method calls deep, and I should roll back the transaction.
If I'm forced to either use checked exceptions or use if statements to check whether there was success at each level, then that's a lot of repeated boilerplate try/catch/rethrow or if(success) code which unchecked exceptions free me up from having to write.
If all I receive at the transaction level is a failure code, then what do I log, other than "something went wrong?!". With exceptions, all the work is done for me. I just log the exception stack trace and I can easily see what needs to be fixed.
Much of the time, exceptions are useful because they are thrown becuase of something you didn't anticipate happening, as opposed to something you had planned for when writing the code. And when that unanticipated thing does happen, there is nothing more beautiful than an automatically generated stack trace telling you exactly what happened.
Re: Isaacs: try/catch is an anti-pattern
#44I think the best is a little of both ways. For instance in python: x = some_dict['meh'] Will raise if 'meh' doesn't exist. If you believe that 'meh' should be there in your program, it's fine to 'let it raise an exception'. However, if 'meh' could be there, it's better to use an error style such as: x = some_dict.getDefault('meh', 'some-neutral-value') And continue without raising because there's no need to raise as…
Re: Isaacs: try/catch is an anti-pattern
#45Earlier quoted context omitted.
This is a bad idea that keeps coming back again and again. I see nothing wrong with exceptions, 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. Languages like Go and Scala roll out various mechanisms that bring us back to the bad old days of C, when we had to check the return/value and or the error co…
> when we had to check the return/value and or the error code after every function call... if we wanted error handling to work. Errors as return values force you to think about every possible error, which is a good thing for code quality. Look at how much rock stable C software we have out there. Software that can be compiled on many different architectures, run in many different environments, and it all just works,…
So my code hasn't had every possible failure case thought through and explicitly handled in advance. That's good. Firstly some of those errors are so rare they'll almost certainly never occur in my program's lifetime; by not having to handle them explicitly and individually I save time and money. Secondly I can guarantee that, no matter how good I think I am, the program will eventually find a way of crashing I'd not considered; this approach gives me a clean means of handling unforeseen errors as well.
A bad programmer can write bad code in any pattern and with any tools. A bad C programmer using return values can create so many different standards for how to handle errors that you might as well get out the divining rods to read the code. Personally, done right (as with anything) I happen to like try...catch.
Re: Isaacs: try/catch is an anti-pattern
#46Isaacs is spot-on, and this is one reason why I love Objective-C. NSException is for programming errors, which should be rare. You can use try/catch, but you almost never do. NSError is for expected application-level errors.
Re: Isaacs: try/catch is an anti-pattern
#47Earlier quoted context omitted.
This is a bad idea that keeps coming back again and again. I see nothing wrong with exceptions, 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. Languages like Go and Scala roll out various mechanisms that bring us back to the bad old days of C, when we had to check the return/value and or the error co…
> when we had to check the return/value and or the error code after every function call... if we wanted error handling to work. Errors as return values force you to think about every possible error, which is a good thing for code quality. Look at how much rock stable C software we have out there. Software that can be compiled on many different architectures, run in many different environments, and it all just works,…
Which would be what exactly. The work of Knuth and djb I'll grant you, but the rest?
Re: Isaacs: try/catch is an anti-pattern
#48I think the best is a little of both ways. For instance in python: x = some_dict['meh'] Will raise if 'meh' doesn't exist. If you believe that 'meh' should be there in your program, it's fine to 'let it raise an exception'. However, if 'meh' could be there, it's better to use an error style such as: x = some_dict.getDefault('meh', 'some-neutral-value') And continue without raising because there's no need to raise as…
You mean collections.defaultdict http://docs.python.org/library/collections.html#collections....
Re: Isaacs: try/catch is an anti-pattern
#49Earlier quoted context omitted.
This is a bad idea that keeps coming back again and again. I see nothing wrong with exceptions, 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. Languages like Go and Scala roll out various mechanisms that bring us back to the bad old days of C, when we had to check the return/value and or the error co…
> when we had to check the return/value and or the error code after every function call... if we wanted error handling to work. Errors as return values force you to think about every possible error, which is a good thing for code quality. Look at how much rock stable C software we have out there. Software that can be compiled on many different architectures, run in many different environments, and it all just works,…
For instance, a system might have plug-ins that get data from a CSV file, a relational database and a web service. One day somebody comes along and adds a plug-in that gets data from a noSQL database.
Add a new component to the system and you introduce not only new failure modes but new ways failure impacts the "system a s a whole."
The more decisions you make, the more you will make wrong decisions. Exceptions provide a reasonable default behavior that is "decision free" and reasonable ways to upgrade it.
20 year old C software lived in a simpler world; only specialized network utilities like telnet and tcpwrappers would have to face the consequences of a failing DNS lookup or the temporarily failure of a network switch in Toledo.
Re: Isaacs: try/catch is an anti-pattern
#50A function which has the same result in case of an error as when given valid input (hint: 'null' is a valid json string) is neither good design, nor something I would actually 'prefer'.
Aside of that (and more to the point of the original article), I do believe that exceptions can be very useful the deeper the abstraction of your libraries gets.
If you are 'far down' the stack and you want to ensure that you are in a position where it's safe to proceed and making it very, very clear for the caller that something went wrong, trow() is the perfect tool in order not to be called with a garbage argument on a successive call to a different function (hint: error results tend to get ignored).
And if you are a user of a library, getting nice exceptions can be very handy too - sometimes even wrapping and re- throwing them.
A very good example of real code: In a command line script which processes a lot of text-data to import into a database delegates to various importer classes depending on import line type.
All these importer classes do their thing and whenever they come across an issue, they just throw an ImporterException with all the context that they know about.
The parent script only has to deal with one single case of Exception to produce nice error messages and show everything about the context where they happened.
I can make the importers as complicated as they need to be and I never have to check a single return value (or forget to check it). There is one central place to handle whatever kind of Error that can creep up.
This is very handy.
Granted, in JS/node where each callback cleans out the stack so that a thrown exception can't be handled by whatever caused the callback to be executed later), exceptions are useless and actually harmful because they can mess up the program flow (which assumes callback to be triggered eventually).
But exceptions being useless in one environment doesn't make the useless everywhere.