At 12:24 15/02/2004, Adam Bregenzer wrote:
On Sat, 2004-02-14 at 11:38, Zeev Suraski wrote:
> >>My experience is a bit of the opposite, and the truth is somewhere in the
> >>middle I guess. But anyway, if you want to error out, why not just do
> >>that? Why go through the mess of coming up with an exception that will
> >>propagate through God knows how many checks and hopefully won't be caught?


It is my understanding that exceptions exist to prevent you from having
to "just error out."

Right, but we're on a bit of an endless circle here. If they're supposed to be caught, let the user catch them, and yes, that includes catch-all functionality, to allow users to recover from problems easily, regardless of the specifics of the exceptions. If they're not supposed to be caught, use errors. We shouldn't design exceptions based on something that's needn't be a design goal.


> >Because you want it to be catchable by someone who is looking for it.
>
> Are you talking about some plugin system where you want to send exceptions
> from lower layers to upper layers, bypassing the user-code in the
> middle?  Otherwise, I don't see why you'd ever want to do that, and that's
> a fairly esoteric case.  If you just want to be able to clean up nicely at
> the extension level or something like that, instead of using
> set_exception_handler() to identify this exception and do something
> special, why not use set_error_handler()?

In a rich object based application there could be multiple levels within
the application itself.  One example I can think of that relates to
conditionally handling exceptions uses data access (pseudo code):

class NoDataException implements Throwable;
class DatabaseException extends Exception implements Throwable;
class MysqlException extends DatabaseException implements Throwable;

function getData($table_name, $key) throws
        NoDataException, DatabaseException {
  $result = mysqlGetData($table_name, $key);
  if ($result == NULL) { // A MySQL error occured
    throw new MysqlException(mysql_get_error());
    return $result;
  } else if $result == 0) { // There were no records
    throw new NoDataException($table_name);
    return $result;
  } else {
    return $result;
  }
}

function doStuff() {
  try {
    $data = getData('table', 2);
  } catch (NoDataException e) {
    // Oops, no data.  Ask for a different key before proceeding.
  }
}

This uses exceptions to propagate an application error that the
application should gracefully handle.  This type of error should be
caught by the application and not passed up.  If it is passed up it is
effectively useless outside of its layer.  It would be more appropriate
for this to be treated as an un-handled exception (bad programming) than
for it to be caught in some mass exception handler and its error dumped
to the screen.  The MysqlException is a system application and could
result in more drastic action.  For example if GUI information is stored
in the database, continuing with the application may not be possible.
If it is possible to continue (backup database, etc.) then the exception
can be handled.  Otherwise it should be handled gracefully later.  In
other words it may be useful for some exceptions to be handled by a
generic exception handler up the propagation chain, however some
exceptions should pass un-handled to php.  Implementing
set_error_handler() in getData or doStuff is sub-optimal because higher
layers may be able to (or need to) handle the exception.  I think a base
exception class as well as a Throwable interface would be a good idea.
However, I do not think all exceptions should be required to inherit
Exception, only implement Throwable.  Another example is using
exceptions to throw validation errors.

I understand mostly everything you say except for why there's any motivation to introduce more headaches in the form of a new Throwable interface, forcing people to become acquainted with interfaces before they can throw an exception. Under the assumption that we want to supply users with catch-all functionality, which is a rock solid assumption, I think that requiring that all exception classes inherit from class Exception is the best solution.


Zeev

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to