php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #69530 A couple of suggestions about new PHP7 exceptions hierarchy
Submitted: 2015-04-25 00:31 UTC Modified: 2016-09-15 14:14 UTC
From: youwish dot spambot at example dot org Assigned: cmb (profile)
Status: Closed Package: *General Issues
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
 [2015-04-25 00:31 UTC] youwish dot spambot at example dot org
Description:
------------
Since basically all languages failed to have a decent exception hierarchy, let's try to not do the same with PHP7.

First of all some short definitions:

"unchecked": errors that SHOULD (usually) NOT BE handled to offer equivalent functionality
"checked": errors that SHOULD (usually) BE handled to offer equivalent functionality

Not saying that PHP should have exceptions in signatures, I'm using these names just for clarity.
What's most important, is to have a correct hierarchy.

I'd start considering Exception the base class for "checked" exceptions.
That's how people use it today, since PHP didn't have anything like "unchecked" exceptions so far.

Currently the exception hierarchy is:

BaseException (abstract)
 +- EngineException
     +- TypeException
 +- ParseException
 +- Exception
     +- AssertionException

How it should be:

Throwable              (was BaseException, abstract)
 +- Error              (was EngineException, unclassified errors)
     +- TypeCheckError (was TypeException)
     +- AssertionError (was AssertionException)
     +- ParseError     (was ParseException)
 +- Exception

So, firstly I don't think it's correct to have AssertionException caught by catch(\Exception $e) blocks.

When one uses a catch(\Exception $e), an alternative implementation is being provided for anything that could have caused an error in the try{} block **while in production**.

When an assert() fails, instead, the developer wants to be informed of the error, rather than executing the code that handles it and that hides what was the expectation / the actual problem.

So I would move that from under Exception.

ParseException is a bit tougher to classify but I believe it's better placed under EngineException since it is an error type that unlikely is going to be handled but rather just logged / debugged. It works fine with siblings and parent since you can easily differentiate using properly ordered catch() blocks:

/* siblings */ catch(ParseError $a){}
/* siblings */ catch(TypeCheckError $b){}
/* siblings */ catch(AssertionError $c){}
               catch(Error $c){}

A more complete, future, exception bundle could be:

Throwable
 +- Error
     +- TypeError
         +- NullPointerError
         +- TypeCheckError 
         +- TypeCastError (like array to string)
     +- AssertionError
     +- ParseError
         +- InclusionParseError
         +- EvaluationError
     +- MathError
         +- DivisionByZeroError
         +- NaNError
 +- Exception

HTH


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-15 14:14 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2016-09-15 14:14 UTC] cmb@php.net
That's pretty close to what we have[1], so this request can be
closed.

[1] <http://php.net/manual/en/language.errors.php7.php>
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jun 01 08:01:26 2025 UTC