Exceptions Primer - 2011-03-23

Exceptions are a critical part of Object Oriented Programming. They are the alternative to what is called “error handling”, which we are not going to go over.

Exceptions should be used to trap and report any unexpected behavior. Just because something is unexpected, however, doesn’t necessarily mean you can’t predict that it may occur

Can you think of any examples of something that you wouldn’t exactly expect but that could occur?

Types of such unexpected but predictable events include

  1. Invalid user input that you wouldn’t normally expect that can cause problems.
  2. Blank user input where it is required and expected.
  3. Hardware issues, such as hard drive failure or the most common unchecked failure: full hard drives. Also corrupted memory, no network, etc.

In PHP, Exceptions are objects. You throw them. and optionally catch them. The syntax goes like this:

        throw new Exception('Description of exception', optional_error_code);
    catch(Exception $e)
        // Code to run after the exception is thrown.

There are two ways to deal with Exceptions. Either “catch” them and decide what to do next, or ignore them, and let PHP kill the application.

Unlike most other languages — including the veritable bastard child of programming / languages, Visual Basic — people who learn only PHP practically never have a knowledge of Exceptions at all. In fact, in unofficial surveys of PHP developers, less than 10% of those who have programmed in PHP exclusively for more than 5 years knew how to handle exceptions. Only 50% knew they existed.

So how do these developers handle exceptions to normal program flow? They by and large don’t! That’s right. The typical, senior-level PHP “engineer” has no ability to trap anything higher than an E_WARNING and simply allows their applications to crash. Hard. Usually resulting in loss of data integrity, irrate customers, and confused engineering teams.

Exceptions are the sane alternative. They allow any competent engineer to prepare for every predictable outcome they can think of, as well as any unpredictable one, like running out of hard drive space or faulty memory. Or even malicious sabotage.

I know you’re thinking, “Exceptions sound great, but do you have any proof PHP developers in particular do not use them? Sounds like FUD to me!” Here’s some evidence:

The only way to even generate errors without using exceptions is to use the function trigger_error(). Knowing this, we can query google for “php trigger_error()” versus “php throw new Exception”. This should give us an objective to answer to what is used most.

  • php + trigger_error() — About 1,720,000 results
  • php + throw new Exception — About 459,000 results
  • java + throw new Exception — About 994,000 results
  • C# + throw new — About 1,360,000 results

Real world data suggests that less than 5% of total PHP error handling.is done using Exceptions, and that a shocking 40% of PHP applications have no error-handling at all.

So how did PHP coders miss the proverbial Exception boat? PHP was created in 1996. It received its largest adoption period between 2000 and 2004 with PHP 4.0. PHP did not support Exceptions, however, until 2004.

“That still doesn’t explain anything. Wouldn’t people have caught on in the last 8 years?” Sadly, that is not the case. PHP is a very efficient language. So efficient that, unlike practically every other programming language, almost anyone is able to create marginally-functional applications with otherwise incredibly-crappy code. After about 4 years of practice, people become masters at producing marginally-function code and wow management by always doing exactly what they are asked to do, quicker than people who would take time and do things right.

Because PHP has very few of the drawbacks of other languages, such as C++’s lack of memory management, Java’s complicated setup procedure, Python’s complicated syntax, or Ruby’s bad memory state, bad PHP code generally will work where it would crash and burn other websites. Because of this, there are very real evolutionary [ … need word … ] that cause these mediocre programmers to not only proliferate in the industry, but believe they know everythign there is to know about programming.

This is why PHP developers are by-and-large completely ignorant of practically all the core concepts of programming, in far greater percentages than any other language, such as Design Patterns, debugging with break points, and even basic code profiling (the technique of discovering performance bottlenecks).

And the trend is only getting worse. As more of these people advance throughout corporate hierarchies, they invariably write books, tutorials, and train new beginners, so that now, in 2011, the vast majority of PHP training material is obsoleted, wrong, or plain missing all of the above mentioned core concpets and much more. This is why there is a trend among corporations to send PHP devs to Java and C++ training courses: because training in things like Design Patterns just does not exist for PHP.

[tsmith] http://repo.phpexperts.pro/source/domainsearch/annotate/head:/API/NameCheap/DomainAvailability.php [tsmith] in public function query() [companyhen] yes [tsmith] Why don’t you tell me what happens if there’s a problem fetching a URL on line 56? [companyhen] it will echo an Error message and add it to the error log? [tsmith] and then? [companyhen] Not sure. [tsmith] Then it returns an empty set, and the app keeps on churning. [companyhen] ah, so return null [tsmith] We’ve *handled* the exception to the point that it’s business as usual as if nothing bad had happened. [tsmith] Now… [tsmith] if this were traditional procedural error handling… it’d be far more compelx. [companyhen] for some reason I was looking at it like an if statement so I was skipping over the null, but I understand now. [tsmith] Let’s pretend that ThriveDownloader::fetch() calls another method which calls another method which does the downloading. [tsmith] that’s 3 levels deep. [tsmith] If we were using traditinoal error handling, we’d have to: [tsmith] 1. Create some sort of arbitrary return value for errors (like -1 for failure1, -2 for failure2, etc.) [tsmith] 2. Modify each and every function all the way down and up the slope to have knowledge of this arbitrary system. [tsmith] 3. Modify each and every function all the way up and down whenever we added new error types, etc. [tsmith] 4. We’d have to do lots of if statements. [tsmith] w/ Exceptions, we largely don’t have to know how the underlying methods work and we don’t have to modify them at all. [companyhen] Cool. [tsmith] All we have to know is that Thrive Downloader will throw a Thrive_URL_Exception if it has problems. [tsmith] So the benefits of Exceptions are: [tsmith] 1. No need to modify the underlying or overlying code to add in error handling support. [tsmith] 2. Very minimal knowledge of the underlying code (just need to know what exceptions it throws under what circumstances). [tsmith] 3. Ability to catch exceptions anywhere in the execution path, from the very bottom to the very top. [tsmith] 4. You can nest exceptions unlike errors. [tsmith] 5. You can far more easily handle exceptions so that they do not crash your app, if you so desire.