The Scourge of Error Handling
CowboyRobot writes "Dr. Dobb's has an editorial on the problem of using return values and exceptions to handle errors. Quoting: 'But return values, even in the refined form found in Go, have a drawback that we've become so used to we tend to see past it: Code is cluttered with error-checking routines. Exceptions here provide greater readability: Within a single try block, I can see the various steps clearly, and skip over the various exception remedies in the catch statements. The error-handling clutter is in part moved to the end of the code thread. But even in exception-based languages there is still a lot of code that tests returned values to determine whether to carry on or go down some error-handling path. In this regard, I have long felt that language designers have been remarkably unimaginative. How can it be that after 60+ years of language development, errors are handled by only two comparatively verbose and crude options, return values or exceptions? I've long felt we needed a third option.'"
Ignoring the error completely, data integrity or planned functioning be damned.
I think MS already tried the blue screen.
It is not clutter. It is necessary. Trash cans in the home might be considered clutter too I suppose. Some people artfully conceal them within cabinets and such, but in whatever form, they are both necessary and either take up space or get in the way or both.
It is the reality we live in. If you want to code in a language that doesn't require error handling, you might look to one of those languages we use to teach 5 year olds how to program in.
Good code does everything needed to manage and filter input, process data accurately and deliver the output faithfully and ensuring that it was delivered well. All of this requires error checking along the way. If you leave it to the language or the OS to handle errors, your running code looks unprofessional and is likely to abort and close for unknown causes.
I think the short of this is that if anyone sees error checking as clutter or some sort of needless burden, they need to not code and to do something else... or just grow up.
The author commends the use of multiple return values and a side-band error value that must be checked? Gee, multiple return values have been in Lisp forever, and maybe he's not aware of this little thing called "errno"?
Error handling is very, very tedious by nature. There are bajillions of ways that a system can go screwy, and many of these have individualized responses that we want distinguished for it to behave intelligently in response. We expect computers to become "smarter", and that means reacting intelligently to these problematic/unexpected situations. That is a lot of behavioral information to imbue into the system, all hooked into precise locations or ranges for which that response is applicable. That information is hard to compress.
I believe the reason for not wanting to throw exceptions unless really needed is that exceptions (and their handling) are relatively expensive and resource intensive operations. Most languages when exceptions are thrown do a lot of runtime stack analysis to, among other things, get a full stack trace. There are many research links on the interweb explaining how expensive it is in whatever language you happen to be using, but here is the first link I found: http://stackoverflow.com/questions/1282252/how-much-more-expensive-is-an-exception-than-a-return-value
.net runtime, throwing an exception was > 1000x as expensive as using a return value, in processing time.
In the case of the
today is spelling optional day.
(You probably know all this, but it might be interesting to someone. One of the sysadmins at work could do with reading it...)
I practically never write scripts for Windows machines, hence never having a genuine use for that VB feature, but on Linux (etc) there's a close-enough equivalent for getting things done; and for shell scripts the default is to continue in case of error. The -e flag to the interpreter prevents this.
#!/bin/sh /put/archives/here /files/to/archive/* /files/to/archive/*
cd
tar cjvf archive-$(date +%Y%m%d).tar.bz2
rm -f
echo "files archived in archive-$(date +%Y%m%d).tar.bz2"
The cd failing (network down? Disc had errors and wasn't mounted? someone moved the directory?) and the tar failing (filesystem suddenly read-only?) won't stop the rm happening, but "#!/bin/sh -e" would.
(Alternatively, tar has a --remove-files option, which would prevent removing a file created since tar was executed, but you could still end up with the archive being put in the wrong place.)
You can let a command fail by using ||, for example:
#!/bin/sh -e /put/archives/here /files/to/archive/* --remove-files
cd
tar cvf archive-$(date +%Y%m%d).tar
xz --best archive-$(date +%Y%m%d).tar || echo "Compression failed"
A well written program doesn't NEED an error handler.
Okay, tough-guy... "The specified network name is no longer available". Explain how you avoid needing to handle that.
Well, it's simple: Sane defaults. Try again with "localhost". What? "localhost" doesn't have anything listening on port 80? system( "apt-get install LAMP" ); It does now. Oh, Apache failed to install? Spawn a thread that opens a socket and listens on port 80. Can't spawn a thread? Cooperative Multitasking mode enabled (hint: function pointers for main loops). Can't listen on port 80? Virtualize a socket in memory, etc.
"Error Handling" Pffffbt, how about a Solution Handler? Hint: Don't focus on the Problem, focus on the Solution. You'd know this already if you posted in HTML mode... It's doesn't throw errors when displaying my malformed post. Quote it and see