PHP Exceptions tips
How to use exceptions properly?

       Damian Sromek
       damiansromek.pl
          2012-05
What's an exception?
Software can not finish task by performing
regular scenario and you should not ignore it.

● External system does not work
  eg. database, network, filesystem
● Software is used/configured wrong
  eg. credentials not set
● There's a bug in software
  eg. somehow program came to invalid state,
  object was requested to do something inappropriate / "stupid"
What's NOT an exception?
Software can not finish a task but you know it's
nothing strange when some criteria are not
met.

● Validator failure
   eg. wrong form field value, wrong credentials when logging in

Database access methods

● findByPK - should return "null" if no unique
  result
● findAll - should return empty collection if no
  results
Main types of exceptions
● LogicException
  Software got to wrong state but it will not
  happen again when programmer fixes the
  code
  eg. filling missing configuration, better form validation


● RuntimeException
  Software got to wrong state because of
  external dependency that could not have
  been avoided any way
  eg. network error, database failure
PHP spl exceptions
http://php.net/manual/en/language.exceptions.php
http://www.php.net/manual/en/spl.exceptions.php
Sadly there's not much about exceptions in PHP documentation.


http://www.php.net/~helly/php/ext/spl/classException.html
Exception
  LogicException
     BadFunctionCallException
       BadMethodCallException
     DomainException
     InvalidArgumentException
     LengthException
     OutOfRangeException
  RuntimeException
     OutOfBoundsException
     OverflowException
     RangeException
     UnderflowException
     UnexpectedValueException
Exceptions instead of PHP errors
Convert PHP errors to exception to get better
control over your software
http://www.php.net/manual/en/class.errorexception.php
<?php
function exception_error_handler ($errno, $errstr, $errfile , $errline ) {
    throw new ErrorException ($errstr, 0, $errno, $errfile , $errline );
}
set_error_handler ("exception_error_handler" );
Problems with exceptions
● Some use them to control the flow of
  application
● Sometimes it's hard to distinguish which
  exception class to use
● Topic is not as much highlighted as it should
  be :(
Benefits (when used properly)
● Software is much more predictable and user
  friendly when there are some problems with
  external system (WebService) etc.
● It's much easier to find out what failed
● It's much easier to find the bug
Main advantages over error flags
(booleans, integers etc.)
● Much less "if" statements which results in
  more maintainable code
● You can explain why software fails by
  sending descriptive message and stack
  trace
Ideal exception
● Tells you what happened, why it happened
  and (if possible) how to fix it.
● Is ideal log message
● Is not thrown ;) Handle error in place where
  it happened if you can.

Eg.

●     new RuntimeException("Could not contact web service [url = $webServiceUrl, httpCode = $httpCode] to log user
      in [user id = $userId].");

●     throw new Canaldigital_PaymentService_Exception('Could not store customer product ' . "[Customer.id =
      {$customer->id}; Product.id = {$product->id}].");

●     throw new Exception("Auth server error"); // NOT!
Layer/library exceptions
● Use spl exceptions as much as possible
● Use "marker interface" to group exceptions
  thrown by library etc.
  eg. like in Symfony2, Zend Framework 2
namespace MyApi;
interface Exception {};
class RuntimeException extends RuntimeException {};
// so you can handle specific module/layer exceptions
try {
...
} catch (MyApiRuntimeException $myApiRuntimeEx) {
...
} catch (MyApiException $myApiEx) {
..
} catch (RuntimeException $runtimeEx) {
...
}
Do NOT!
● empty try-catch

  If you don't know what to do with
  exception/error just let it go up!

  At the point when context let you decide
  what to do now you can handle it in the right
  way.
PHPDoc
@throws DbException on DB error
or even better
@throws MethodNotAllowedHttpException //
self describing
Testing exceptions
● @expectedException
  InvalidArgumentException
● @expectedExceptionMessage Right
  Message (@see assertContains)
● @expectedExceptionCode 20
● http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.
    html#writing-tests-for-phpunit.exceptions
Appendix A - Exceptions in PHP doc
class LogicException extends Exception
Exception that represents error in the program logic.
This kind of exceptions should directly leed to a fix in your code
- Exception that represents error in the program logic. This kind of exceptions should directly lead to a fix in your code.


class BadFunctionCallException extends LogicException
Exception thrown when a function call was illegal.
- Exception thrown if a callback refers to an undefined function or if some arguments are missing.


class BadMethodCallException extends BadFunctionCallException
Exception thrown when a method call was illegal
- Exception thrown if a callback refers to an undefined method or if some arguments are missing.


class DomainException extends LogicException
Exception that denotes a value not in the valid domain was used.
This kind of exception should be used to inform about domain erors in mathematical sense.
- Exception thrown if a value does not adhere to a defined valid data domain.


class InvalidArgumentException extends LogicException
Exception that denotes invalid arguments were passed.
- Exception thrown if an argument does not match with the expected value.
Appendix A - Exceptions in PHP doc
class LengthException extends LogicException
Exception thrown when a parameter exceeds the allowed length.
This can be used for strings length, array size, file size, number of elements read from an Iterator and so on.
- Exception thrown if a length is invalid.


class OutOfRangeException extends LogicException
Exception thrown when an illegal index was requested.
This represents errors that should be detected at compile time.
- Exception thrown when an illegal index was requested. This represents errors that should be detected at compile time.


class RuntimeException extends Exception
Exception thrown for errors that are only detectable at runtime.


class OutOfBoundsException extends RuntimeException
Exception thrown when an illegal index was requested.
This represents errors that cannot be detected at compile time.
- Exception thrown if a value is not a valid key. This represents errors that cannot be detected at compile time.


class OverflowException extends RuntimeException
Exception thrown to indicate arithmetic/buffer overflow.
- Exception thrown when adding an element to a full container.
Appendix A - Exceptions in PHP doc
class RangeException extends RuntimeException
Exception thrown to indicate range errors during program execution.
Normally this means there was an arithmetic error other than under/overflow. This is the runtime version of DomainException.
- Exception thrown to indicate range errors during program execution. Normally this means there was an arithmetic error other than under/overflow. This is the runtime version of
DomainException.


class UnderflowException extends RuntimeException
Exception thrown to indicate arithmetic/buffer underflow.
- Exception thrown when performing an invalid operation on an empty container, such as removing an element.


UnexpectedValueException extends RuntimeException
- Exception thrown if a value does not match with a set of values. Typically this happens when a function calls another function and expects the return value to be of a certain type
or value not including arithmetic or buffer related errors.
Thank you :)

Php exceptions

  • 1.
    PHP Exceptions tips Howto use exceptions properly? Damian Sromek damiansromek.pl 2012-05
  • 2.
    What's an exception? Softwarecan not finish task by performing regular scenario and you should not ignore it. ● External system does not work eg. database, network, filesystem ● Software is used/configured wrong eg. credentials not set ● There's a bug in software eg. somehow program came to invalid state, object was requested to do something inappropriate / "stupid"
  • 3.
    What's NOT anexception? Software can not finish a task but you know it's nothing strange when some criteria are not met. ● Validator failure eg. wrong form field value, wrong credentials when logging in Database access methods ● findByPK - should return "null" if no unique result ● findAll - should return empty collection if no results
  • 4.
    Main types ofexceptions ● LogicException Software got to wrong state but it will not happen again when programmer fixes the code eg. filling missing configuration, better form validation ● RuntimeException Software got to wrong state because of external dependency that could not have been avoided any way eg. network error, database failure
  • 5.
    PHP spl exceptions http://php.net/manual/en/language.exceptions.php http://www.php.net/manual/en/spl.exceptions.php Sadlythere's not much about exceptions in PHP documentation. http://www.php.net/~helly/php/ext/spl/classException.html Exception LogicException BadFunctionCallException BadMethodCallException DomainException InvalidArgumentException LengthException OutOfRangeException RuntimeException OutOfBoundsException OverflowException RangeException UnderflowException UnexpectedValueException
  • 6.
    Exceptions instead ofPHP errors Convert PHP errors to exception to get better control over your software http://www.php.net/manual/en/class.errorexception.php <?php function exception_error_handler ($errno, $errstr, $errfile , $errline ) { throw new ErrorException ($errstr, 0, $errno, $errfile , $errline ); } set_error_handler ("exception_error_handler" );
  • 7.
    Problems with exceptions ●Some use them to control the flow of application ● Sometimes it's hard to distinguish which exception class to use ● Topic is not as much highlighted as it should be :(
  • 8.
    Benefits (when usedproperly) ● Software is much more predictable and user friendly when there are some problems with external system (WebService) etc. ● It's much easier to find out what failed ● It's much easier to find the bug
  • 9.
    Main advantages overerror flags (booleans, integers etc.) ● Much less "if" statements which results in more maintainable code ● You can explain why software fails by sending descriptive message and stack trace
  • 10.
    Ideal exception ● Tellsyou what happened, why it happened and (if possible) how to fix it. ● Is ideal log message ● Is not thrown ;) Handle error in place where it happened if you can. Eg. ● new RuntimeException("Could not contact web service [url = $webServiceUrl, httpCode = $httpCode] to log user in [user id = $userId]."); ● throw new Canaldigital_PaymentService_Exception('Could not store customer product ' . "[Customer.id = {$customer->id}; Product.id = {$product->id}]."); ● throw new Exception("Auth server error"); // NOT!
  • 11.
    Layer/library exceptions ● Usespl exceptions as much as possible ● Use "marker interface" to group exceptions thrown by library etc. eg. like in Symfony2, Zend Framework 2 namespace MyApi; interface Exception {}; class RuntimeException extends RuntimeException {}; // so you can handle specific module/layer exceptions try { ... } catch (MyApiRuntimeException $myApiRuntimeEx) { ... } catch (MyApiException $myApiEx) { .. } catch (RuntimeException $runtimeEx) { ... }
  • 12.
    Do NOT! ● emptytry-catch If you don't know what to do with exception/error just let it go up! At the point when context let you decide what to do now you can handle it in the right way.
  • 13.
    PHPDoc @throws DbException onDB error or even better @throws MethodNotAllowedHttpException // self describing
  • 14.
    Testing exceptions ● @expectedException InvalidArgumentException ● @expectedExceptionMessage Right Message (@see assertContains) ● @expectedExceptionCode 20 ● http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit. html#writing-tests-for-phpunit.exceptions
  • 15.
    Appendix A -Exceptions in PHP doc class LogicException extends Exception Exception that represents error in the program logic. This kind of exceptions should directly leed to a fix in your code - Exception that represents error in the program logic. This kind of exceptions should directly lead to a fix in your code. class BadFunctionCallException extends LogicException Exception thrown when a function call was illegal. - Exception thrown if a callback refers to an undefined function or if some arguments are missing. class BadMethodCallException extends BadFunctionCallException Exception thrown when a method call was illegal - Exception thrown if a callback refers to an undefined method or if some arguments are missing. class DomainException extends LogicException Exception that denotes a value not in the valid domain was used. This kind of exception should be used to inform about domain erors in mathematical sense. - Exception thrown if a value does not adhere to a defined valid data domain. class InvalidArgumentException extends LogicException Exception that denotes invalid arguments were passed. - Exception thrown if an argument does not match with the expected value.
  • 16.
    Appendix A -Exceptions in PHP doc class LengthException extends LogicException Exception thrown when a parameter exceeds the allowed length. This can be used for strings length, array size, file size, number of elements read from an Iterator and so on. - Exception thrown if a length is invalid. class OutOfRangeException extends LogicException Exception thrown when an illegal index was requested. This represents errors that should be detected at compile time. - Exception thrown when an illegal index was requested. This represents errors that should be detected at compile time. class RuntimeException extends Exception Exception thrown for errors that are only detectable at runtime. class OutOfBoundsException extends RuntimeException Exception thrown when an illegal index was requested. This represents errors that cannot be detected at compile time. - Exception thrown if a value is not a valid key. This represents errors that cannot be detected at compile time. class OverflowException extends RuntimeException Exception thrown to indicate arithmetic/buffer overflow. - Exception thrown when adding an element to a full container.
  • 17.
    Appendix A -Exceptions in PHP doc class RangeException extends RuntimeException Exception thrown to indicate range errors during program execution. Normally this means there was an arithmetic error other than under/overflow. This is the runtime version of DomainException. - Exception thrown to indicate range errors during program execution. Normally this means there was an arithmetic error other than under/overflow. This is the runtime version of DomainException. class UnderflowException extends RuntimeException Exception thrown to indicate arithmetic/buffer underflow. - Exception thrown when performing an invalid operation on an empty container, such as removing an element. UnexpectedValueException extends RuntimeException - Exception thrown if a value does not match with a set of values. Typically this happens when a function calls another function and expects the return value to be of a certain type or value not including arithmetic or buffer related errors.
  • 18.