rfc:throwable-interface

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:throwable-interface [2015/05/24 19:50] trowskirfc:throwable-interface [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 3: Line 3:
   * Date: 2015-05-22   * Date: 2015-05-22
   * Author: Aaron Piotrowski <aaron@icicle.io>   * Author: Aaron Piotrowski <aaron@icicle.io>
-  * Status: Under Discussion+  * Status: Accepted
   * First Published at: http://wiki.php.net/rfc/throwable-interface   * First Published at: http://wiki.php.net/rfc/throwable-interface
  
Line 32: Line 32:
  
 The reason an object named ''TypeException'' would not be caught by ''catch (Exception $e)'' is not obvious. The ''Exception'' suffix implies that ''TypeException'' extends ''Exception''. If the name of the thrown class was ''TypeError'' it would be much clearer that the class does not extend ''Exception'', but rather is part of a different class hierarchy that must be caught separately. The reason an object named ''TypeException'' would not be caught by ''catch (Exception $e)'' is not obvious. The ''Exception'' suffix implies that ''TypeException'' extends ''Exception''. If the name of the thrown class was ''TypeError'' it would be much clearer that the class does not extend ''Exception'', but rather is part of a different class hierarchy that must be caught separately.
 +
 +To catch the ''TypeException'', the user must write code like this:
 +
 +<code php>
 +function add(int $left, int $right) {
 +    return $left + $right;
 +}
 +
 +try {
 +    echo add('left', 'right');
 +} catch (Exception $e) {
 +    // Handle exception
 +} catch (TypeException $e) { // Appears to descend from Exception
 +    // Log error and end gracefully
 +}
 +</code>
  
 ===== Proposal ===== ===== Proposal =====
Line 43: Line 59:
  
 ''BaseException'' will be removed. ''BaseException'' will be removed.
 +
 +Note that ''ParseError'' extends ''Error'', whereas ''ParseException'' extended ''BaseException''. This allows users to handle everything that used to be an error in a single catch block, while still allowing the flexibility of handling both separately if desired.
  
 Only objects that implement the ''Throwable'' interface can be thrown. The proposed patch does not allow userland classes to implement the ''Throwable'' interface. Instead all classes declared in userland must extend one of the existing exception classes. Only objects that implement the ''Throwable'' interface can be thrown. The proposed patch does not allow userland classes to implement the ''Throwable'' interface. Instead all classes declared in userland must extend one of the existing exception classes.
Line 57: Line 75:
 While both ''Exception'' and ''Error'' are implemented using the same code in the interpreter, the ''Throwable'' interface does not preclude future classes from implementing the interface differently or from the implementation of ''Exception'' and ''Error'' to be different in the future. While both ''Exception'' and ''Error'' are implemented using the same code in the interpreter, the ''Throwable'' interface does not preclude future classes from implementing the interface differently or from the implementation of ''Exception'' and ''Error'' to be different in the future.
  
-''catch (Error $e)'' and ''catch (Throwable $e)'' may be used to catch respectively ''Error'' objects or any ''Throwable'' (current or future) object. Users should be discouraged from catching ''Error'' objects except for logging or cleanup purposes as ''Error'' objects represent coding problems that should be fixed rather than runtime conditions that may be handled.+''catch (Error $e)'' and ''catch (Throwable $e)'' may be used to catch respectively ''Error'' objects or any ''Throwable'' (current or future) object. Users should generally be discouraged from catching ''Error'' objects except for logging or cleanup purposes as ''Error'' objects represent coding problems that should be fixed rather than runtime conditions that may be handled.
  
 After this proposed change, it would be clearer in the example above that another catch block is needed if the user wishes to log errors and end the script gracefully. After this proposed change, it would be clearer in the example above that another catch block is needed if the user wishes to log errors and end the script gracefully.
Line 70: Line 88:
 } catch (Exception $e) { } catch (Exception $e) {
     // Handle exception     // Handle exception
-} catch (Error $e) {+} catch (Error $e) { // Clearly a different type of object
     // Log error and end gracefully     // Log error and end gracefully
 } }
Line 81: Line 99:
  
 Conceptually both of these conditions are error conditions detected by PHP. The only difference is that for some errors the execution of the script can continue from where the error occurred; for others it is not possible for execution to continue from the place where the error occurred, and so instead an exception must be thrown. Conceptually both of these conditions are error conditions detected by PHP. The only difference is that for some errors the execution of the script can continue from where the error occurred; for others it is not possible for execution to continue from the place where the error occurred, and so instead an exception must be thrown.
- 
-Users may wish to use ''set_error_handler()'' to throw objects extending ''Error'' in their code for non-fatal types of error. 
  
 While this name may also cause some confusion for users, other name choices such as ''Failure'' do not seem appropriate. It is likely that users would use the term 'Uncaught Error' when searching, minimizing overlap with with non-fatal error messages. While this name may also cause some confusion for users, other name choices such as ''Failure'' do not seem appropriate. It is likely that users would use the term 'Uncaught Error' when searching, minimizing overlap with with non-fatal error messages.
Line 101: Line 117:
 ===== Voting ===== ===== Voting =====
 A majority of 50%+1 is required to approve this RFC. A majority of 50%+1 is required to approve this RFC.
 +
 +Please remember that this vote is not about creating separate exception branches, as that decision was made in the [[https://wiki.php.net/rfc/engine_exceptions_for_php7|Exceptions in the Engine RFC]]. This vote is about having short, concise, more intuitive names that clarify the separation rather than obfuscating it. ''Throwable'' and ''Error'' make stacked catch blocks cleaner with more obvious behavior. Voting no means keeping ''BaseException'', ''EngineException'', etc. that do not extend ''Exception'', but are named as though they do.
 +
 +Voting opened June 10th, 2015 and remained open until June 17th, 2015.
 +
 +<doodle title="Throwable Interface" auth="trowski" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
  
 ===== References ===== ===== References =====
rfc/throwable-interface.1432497042.txt.gz · Last modified: 2017/09/22 13:28 (external edit)