tags:

views:

353

answers:

2

Sadly, I have a legacy PHP4 system that I continuously need to add features to. It doesn't look like there will be resources to do a port to PHP5 for several months if not several years. Over the course of the past few years, one of the major things that has bothered me is not having the ability to throw exceptions cleanly. Because of this, all kinds of error checking code has to constantly interrupt the flow of what's going on.

So on to the question: What is the best strategy that you have seen to emulate the cleanliness of exception handling in languages that have no exception model?

Joel has this to say regarding exceptions as noted in an answer:

http://www.joelonsoftware.com/items/2003/10/13.html

They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don't catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn't think about.

A better alternative is to have your functions return error values when things go wrong, and to deal with these explicitly, no matter how verbose it might be. It is true that what should be a simple 3 line program often blossoms to 48 lines when you put in good error checking, but that's life, and papering it over with exceptions does not make your program more robust. I think the reason programmers in C/C++/Java style languages have been attracted to exceptions is simply because the syntax does not have a concise way to call a function that returns multiple values, so it's hard to write a function that either produces a return value or returns an error.

However, a good exception model in a language makes the called function specify that it will in fact throw an exception. This implies that there are exaactly zero additional places for the function to exit from (the code would just return false instead of throwing an exception), but there is exactly 1 additional place for the function to exit to... The catch block of the calling function. Anyone can write sloppy code that passes all exceptions upward to be dealt with by others , but that doesn't mean you should take away a tool that can be used cleanly and efficiently.

In fact, any function can return a value that is out of range of the expected return values from the calling code. A good programmer is going to deal with all possible return values, including error codes and conditions. The exception model just gives him a way to do it cleanly.

A: 

Continuation passing style. In fact, I'd venture to say that it beats exceptions in terms of "prettyness". It's not the most natural thing to fit into PHP, but you can do it, using objects and patterns such as visitor.

But really, upgrading from PHP4 to PHP5 doesn't need to be more than a few hours work - it's mostly backwards compatible.

troelskn
-1 for "only a few hours of work". File under famous lies I've told myself :)
Alan Storm
Understanding sympathies @ Alan, been there, bought the t-shirt, the souvenir mug, rustic hat and a time-share =)
David Thomas
haha @Alan - indeed. Not to mention that retrofitting an existing codebase to use CPS could be a herculean task unto it's own.
Peter Bailey
not to mention that CPS is designed for function programming as opposed to imperative programming. (I did say PHP, not Haskell)
Zak
Obviously the porting effort depends on the situation, but I *did* port a php4 app in one days work.
troelskn
Rewriting the entire code base to a CPS would be daft. It can be used strategically. And saying that "CPS was designed for Haskell" is missing the point completely. It's a technique which can be used in any language.
troelskn
I said CPS was designed for functional languages, not imperative ones. But I see the typo in my comment, so I can understand the confusion.
Zak
+2  A: 

First of all, there are some people that think exceptions aren't the right error model anway, including one of the founders of this site.

Secondly, is to try to take an inventory of what error-handling functions are available for your minor version of PHP. My immediate reaction is to suggest spending time writing a good error handler, and register it.

Then, in your application execution where you would normally throw exceptions, you can instead trigger errors. If you are lucky, you will be able to use debug_backtrace().

Good luck!

Peter Bailey
I have actually looked at creating a good error handler, but I haven't figured out a way to keep local error handling in the local file. One thought was to use the results of debug_backtrace to figure out the current class, then call a specific "handle_error" method on that class. What do you think?
Zak
I definitely think that could work - but I have to be honest - I haven't worked with PHP4 in probably 3 years. Maybe longer. Stop by and leave a comment here if you manage to get it working!
Peter Bailey