Published 2004-06-18 07:57:31

PEAR dev is hot with the exception fever at present, The OO purists are beating down the door requesting the eviction of that horible legacy of a bygone age, PEAR_Error. And hoisting the flag of the Exception god at the gates.

Well, It's not really that bad, but it made a fun read. But as Jeff Moore Points out, Exceptions in PHP5, will (and have now) open a whole new can of worms.

Probably like alot of people, with this on the horizon,I have been interested to see last years timely ramblings of Joel that exceptions are evil, not that I always agree with him, but his arguments are rarely too flawed. There followed a huge weblog back and forth about the Greatness and Disaster that Exceptions brought (all this without any reference to the earthquake about to occur in PHP).

I've generally suffered with exceptions, I've hacked on programs written in C#, Java and Python, and found that errors raised by Exceptions tended to be very cryptic, and confusing messages. Perhaps partly due the lack of context information, like line numbers, that is displayed by those languages. But probably Just as frequently by the horrific coding of

throw new MyWgtException()

Ok - so you have your own exception class, but am I expected to guess what the authors abbreviations mean?

One of the beautys of PHP4 is that it allows you to do simple things simply, and complex things without the hastle. Without exceptions, It's very easy to let things fail, and not care about it. Ok, it's not perfect programming, but There are levels of failure that you really do not care about. PHP's often emits E_WARN on a variety of code (reading from unassigned variables etc.), that would not justify a Exception. Similarly, In PEAR, there are many situations where if something failed, It is not that critical.. (like updating a database row, but there is no new data applied).

I do ponder sometimes what would be the answer for Exceptions, is throw always the way to go?

function myblobby() {
    return new Exception("There was a problem with myblobby()");
}
function myblobbyDie() {
throw new Exception("There was a problem with myblobby()");
}


$object->myblobby()->doSomething();
Could that be made to throw an Exception, even though the myblobby call is not normally fatal? could this be done? - without the intervention of PHP core?, possibly?


class Log_Exception extends Exception {
     function __call() {
            throw $this;
     }
     function __get() {
            throw $this;
     }
     function __set() {
            throw $this;
     }
}

Realistically, PEAR classes should probably impliment their own exceptions (eg. Log_Exception), the theory always was that, Packages where supposed to implement their own _Error class, that included usefull things like translations of error messages..

Just returning exceptions, rather than throwing them, at least goes some way towards making them more usefull, although it would be better if PHP core could check if an Exception was returned, within a try {} catch () {} block, that catch was actually called..


Mentioned By:
google.com : april ( referals)
google.com : december ( referals)
google.com : php catch warning ( referals)
google.com : php5 debugger ( referals)
www.procata.com : Jeff Moore's Blog » Exceptional PHP ( referals)
google.com : php5 stack trace ( referals)
google.com : php try catch warning ( referals)
google.com : php5 __set ( referals)
google.com : php stacktrace ( referals)
google.com : php5 debug ( referals)
google.com : php5 catch warning ( referals)
google.com : Kannan Goundan ( referals)
google.com : php catch warning messages ( referals)
google.com : PHP5 try catch warning ( referals)
www.cavorite.com : ( referals)
google.com : catch warning php ( referals)
google.com : php "catch warning" ( referals)
google.com : php print stack trace ( referals)
google.com : PHP try catch warnings ( referals)
google.com : catch warning php5 ( referals)

Comments

I think Exceptions are simply a different way of thinking about code -- and how execution and errors relate. I think people w/ different development backgrounds are just going to disagree on this. It's clear that many PHP developers (and notably PEAR developers) are quite a bit more comfortable with returning error codes.

I think that exceptions are particularly useful in a transactional environment. Most of my development has evolved around database APIs and so thinking in terms of transactions is fairly natural to me. When working with code in that way it's simply not true that it's better to return an error code and deal with it -- even if Joel says so. The fact is that it's a waste of time: I don't care to know that a specific operation failed; I just want the whole thing rolled back or otherwise aborted.

The fact is that when I look through the PEAR and Horde code that I use on a daily basis I very rarely see any sort of "dealing with error codes" happening. What I see is:

if (PEAR::isError($res)) return $res;

So manual checking has to happen for every function call at every level of the stack, and the error isn't resolved it's just bounced up to the calling function, which in turn is responsible for passing it back up the stack. And of course you only have to forget to check one method result to have a nasty (and much harder to debug than uncaught exception) E_FATAL.

What I'd like to know is explicitly what code is it in PEAR or PEAR-derived frameworks that is going to suffer as a result of not using PEAR_Error? I have seen nothing yet that doesn't require fewer lines of code to provide a solution with more flexibility. I've used PEAR_Error and other return-code solutions for years & have had nothing but trouble -- especially with lost errors, and elaborate if/then logic to achieve the goto-style "abort!" that is provided so simply by a throw. I've used PHP5 for I guess almost a year now & have absolutely loved the new error handling model.

Of course, exceptions aren't for everything. For the other stuff (WARNING, NOTICE) there's trigger_error(). I definitely disagree with the suggestion that it's better to lose some errors; if an error is to be ignored I believe it should be explicitly ignored -- i.e. w/ a try/catch block that squelches the error -- rather than just "lost" thanks to the error handler.

Hans
#0 - Hans ( Link) on 2004-06-18 11:43:40 Delete Comment
Hi,

I have been around in coding both procedural (thanks to PHP) and OO-style quite some time. I, too, don't agree with Joel.

Though his arguments are basically right, exceptions, when carefully used (here we have that magic phrase again), are far more powerful, then conventional error handling, as they don't force you to handle errors directly as a callee, but allows you to let someone above you in the call stack deal with them. While implmenenting the Midgard Components (www.midcom-project.org) I would have given much for such a kind of error handling within PHP.

As for being difficult to debug: Here I too disagree: First, for all those gifted that do not hesitate to look into a debugger and actually carefully read the complete exception with its stacktrace, it is usually easy to judge where a given error comes from, and what actually triggered it. This, of course, means that Joe Progammer needs to actually write an error message other then "Joe was dumb" or "This should not happen" in their exceptions. Also, it is often useful to reuse the exception classes the framework gives you as much as possible/sensible.

Summarizing: I find exceptions one of the most important features of modern languages, especially from the view of a framework designer -- if used carefully. But, after all, isn't every task of programming a to-be-used-carefully one?

Torben
#1 - Torben Nehmer ( Link) on 2004-06-21 15:01:37 Delete Comment
I think exceptions are generally better than error returns. Joel's arguments don't really hold water:

Argument 1. Exceptions are invisible in the source code.

If you ignore error return values (which involves no work at all), they won't be visible in the source code either. If you merely want to forward an exception upwards, then use a checked exception to force acknowledgement of the exception somewhere along the line.

Argument 2. Exceptions create too many possible exit points.

You have to do extra thinking to make code exception-safe, but this is how code should be anyway. If you were using error returns, then you'd have to deal with each possible error explicitly, resulting in a similar number of possible exit points. The fact that you don't see the exit points forces you to think about the transactional structure of your code, which makes it more robust (i.e. you can change the invoked code to possibly throw exceptions and everything will still work).

He also says: "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."

Why make your code much longer (and probably much harder to understand or modify) when exceptions provide mechanisms to make it more concise? Oh yeah...because "that's life".


I think the general aversion to exceptions is caused by the syntax. For one, it's inconvenient to write an entire try block if you only want to check a single line of code. It would be nice to be able to say:

OpenFile("goose.txt")
: catch(e) { print("Couldn't open file"); return; }


A danger with error return values is that they can easily be ignored, which could result in the program entering an inconsistent state.

Exceptions don't apply everywhere, but where they do, they are better than error return values. The only problem is the imperfect syntax/semantics in current languages, but it's just a matter of time before people solve that problem.

Exceptions seem to add is an additional leve of complexity thoughout your entire program. You have to be ready for things to fail almost anywhere. The only thing is that this was always true. Exceptions haven't increased the possibility of failure, they've just forced you to acknowledge and deal with the possibility (or be explicit about ignoring it).
#2 - Kannan Goundan ( Link) on 2004-07-31 02:04:19 Delete Comment
I agree with Torben. I first encountered exceptions in Java (cpsc 220 Prin. of Comp. Sci. II) and thought they were a bit overkill. Now that I've gained more experience, and am using .NET nearly every day (please don't hurt me), I am finding that the stack trace is just as useful as any error message; it even tells you right where to find this "invisible goto!" With the combination of a stack trace, a reasonable error message, and the exception's type, debugging has been exceptionally easier for me.

I am looking forward to my web host upgrading next week so I can use this feature in PHP5

J
#3 - Jeremy Voorhis ( Link) on 2004-08-12 05:41:49 Delete Comment
exceptions in java are an overkill, cause they have checked ones. Checked exceptions are a nifty idea with awful effects on the real life.

I don't buy that 'exceptions are not informative, they usually are much more clear then invisible error handling say, stupid ruby code:
$ cat >>boom.rb
def foo_func
boom
end
def goo_func
foo()
end

puts( goo() )
$ ruby boom.rb
boom.rb:2:in `foo_func': undefined local variable or method `boom' for main:Object (NameError)
from boom.rb:5:in `goo_func'
from boom.rb:8

how can it be more informative?

Anyway I hoped php5 included restartable exceptions a-la SmallTalk and implicit try/ for every code block.
This things are life savers and make coding with exceptions a breeze.
#4 - verbat ( Link) on 2004-08-19 03:47:38 Delete Comment

Add Your Comment

Follow us on