Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Exception handling - classic and fancy

Exception handling - classic and fancy

Exceptions are an integral part of PHP. PHP introduced them long ago, but handling has changed over the last versions. So the classic part contains a solid introduction to exception architecture, handling and how to use it. The fancy part will show some examples about modern exception logging.

C739f65cecbb38923d95e9b7cc0d2e63?s=128

Tommy Mühle

January 30, 2017
Tweet

Transcript

  1. Tommy Mühle | tommy-muehle.io Exception handling classic & fancy 1

  2. Tommy Mühle | tommy-muehle.io Tommy Mühle 
 Software Engineer Author

    2
  3. Tommy Mühle | tommy-muehle.io What is an Exception? 3

  4. Tommy Mühle | tommy-muehle.io Tommy Mühle | tommy-muehle.io 4 „An

    exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.“ https:/ /docs.oracle.com
  5. Tommy Mühle | tommy-muehle.io 5 http://php.net/manual/en/class.exception.php

  6. Tommy Mühle | tommy-muehle.io 6 http://php.net/manual/en/class.errorexception.php

  7. Tommy Mühle | tommy-muehle.io Catching 7

  8. Tommy Mühle | tommy-muehle.io 8 /* @var $connection \Doctrine\DBAL\Connection */

    $connection->beginTransaction(); try { // ... $connection->commit(); } catch (\Exception $exception) { $connection->rollBack(); throw $exception; }
  9. /* @var $connection \Doctrine\DBAL\Connection */ $connection->beginTransaction(); try { // ...

    $connection->commit(); } catch (Doctrine\DBAL\DBALException $exception) { $connection->rollBack(); } catch (\Exception $exception) { // ... throw $exception; } Tommy Mühle | tommy-muehle.io 9
  10. Tommy Mühle | tommy-muehle.io 10 /* @var $connection \Doctrine\DBAL\Connection */

    $connection->beginTransaction(); try { // ... $connection->commit(); } catch (\Exception $exception) { $connection->rollBack(); throw $exception; } finally { /* @var $logger \Monolog\Logger */ $logger->info('...'); }
  11. Tommy Mühle | tommy-muehle.io If you throw something, you have

    to catch it. 11
  12. Tommy Mühle | tommy-muehle.io Handling 12

  13. Tommy Mühle | tommy-muehle.io 13 function my_handler($exception) { echo 'Got

    it: ' . $exception->getMessage(); } set_exception_handler('my_handler'); throw new Exception('Take this!');
  14. Tommy Mühle | tommy-muehle.io PHP version specifications 14

  15. Tommy Mühle | tommy-muehle.io PHP 5 15

  16. Tommy Mühle | tommy-muehle.io PHP 5 16

  17. Tommy Mühle | tommy-muehle.io It’s dead, Jim. 17

  18. Tommy Mühle | tommy-muehle.io Exception hierarchy 18

  19. Tommy Mühle | tommy-muehle.io 19 http://php.net/manual/en/spl.exceptions.php

  20. Tommy Mühle | tommy-muehle.io Error as exception 20

  21. Tommy Mühle | tommy-muehle.io 21 function exception_error_handler ($severity, $message, $file,

    $line) { throw new ErrorException ($message, 0, $severity, $file, $line); } set_error_handler('exception_error_handler'); strpos(); // Trigger exception
  22. Tommy Mühle | tommy-muehle.io PHP 7 22

  23. Tommy Mühle | tommy-muehle.io PHP 7 22

  24. Tommy Mühle | tommy-muehle.io NEW Advanced exception hierarchy 23

  25. Tommy Mühle | tommy-muehle.io 24 http://php.net/manual/en/language.errors.php7.php

  26. Tommy Mühle | tommy-muehle.io 25 http://php.net/manual/en/class.throwable.php

  27. Tommy Mühle | tommy-muehle.io 26 http://php.net/manual/en/class.error.php

  28. Tommy Mühle | tommy-muehle.io 27 try { // ... }

    catch (Error $error) { // ... } catch (Exception $exception) { // ... }
  29. Tommy Mühle | tommy-muehle.io PHP 7.1 28

  30. Tommy Mühle | tommy-muehle.io Catching Multiple Exception Types 29

  31. try { // ... } catch (LengthException | OutOfRangeException $exception)

    { // ... } catch (Exception $exception) { // ... } Tommy Mühle | tommy-muehle.io 30
  32. Tommy Mühle | tommy-muehle.io Throw Error in Extensions 31

  33. Tommy Mühle | tommy-muehle.io 32 try { $myDateTime = unserialize('O:8:"DateTime":...";}');

    // ... } catch (Error $error) { // ... }
  34. Tommy Mühle | tommy-muehle.io Best practices 33

  35. Tommy Mühle | tommy-muehle.io Build custom exceptions upon SPL ones.

    34
  36. class FileNotFoundException extends InvalidArgumentException { } class FileNotReadableException extends RuntimeException

    { } Tommy Mühle | tommy-muehle.io 35 Build upon SPL exceptions
  37. Tommy Mühle | tommy-muehle.io Differentiate between logical and runtime exceptions.

    36
  38. Tommy Mühle | tommy-muehle.io Help developers with creating logical exceptions.

    37
  39. Tommy Mühle | tommy-muehle.io Create unavoidable
 runtime exceptions 
 if

    necessary. 38
  40. Tommy Mühle | tommy-muehle.io Create fully qualified 
 named exceptions.

    39
  41. Tommy Mühle | tommy-muehle.io 40 class NotFoundException extends Exception {

    // ... } Avoid unconcrete names
  42. class FileNotReadableException extends RuntimeException { } Tommy Mühle | tommy-muehle.io

    41 Use fully qualified names
  43. Tommy Mühle | tommy-muehle.io Add codes for 
 your exceptions.

    42
  44. Tommy Mühle | tommy-muehle.io 43 class FileNotReadableException extends RuntimeException {

    public function __construct(string $filename) { $message = sprintf('Cannot read %s!', $filename); $code = 666; parent::__construct($message, $code, null); } } Use specific codes
  45. Tommy Mühle | tommy-muehle.io Use named constructors for specific use

    cases. 44
  46. Tommy Mühle | tommy-muehle.io 45 $url = 'unreachable.tld'; if (''

    === $url) { throw new InvalidUrlException('Blank url are invalid!'); } if ('' === parse_url($url, PHP_URL_SCHEME)) { $message = sprintf('The url %s has no scheme!', $url); throw new InvalidUrlException($message); } // ... Avoid inline message generation
  47. Tommy Mühle | tommy-muehle.io 46 class InvalidUrlException extends InvalidArgumentException {

    private static function create(string $reason) { return new static($reason); } public static function blankUrl() { return static::create('Blank url are invalid!'); } } Use named constructors
  48. Tommy Mühle | tommy-muehle.io 47 class InvalidUrlException extends InvalidArgumentException {

    // ... public static function blankUrl() { return static::create('Blank url are invalid!'); } public static function noScheme(string $url) { $reason = sprintf('The url %s has no scheme!', $url); return static::create($reason); } // ... } One method for each case
  49. Tommy Mühle | tommy-muehle.io 48 $url = 'unreachable.tld'; if (''

    === $url) { throw InvalidUrlException::blankUrl(); } if ('' === parse_url($url, PHP_URL_SCHEME)) { throw InvalidUrlException::noScheme($url); } // ...
  50. Tommy Mühle | tommy-muehle.io Centralize own perseverative exceptions. 49

  51. Tommy Mühle | tommy-muehle.io Writing code to support PHP 5.x

    and 7 exceptions. 50
  52. Tommy Mühle | tommy-muehle.io 51 try { // Code that

    may throw an Exception or Error. } catch (Throwable $exception) { // Executed only in PHP 7, // will not match in PHP 5.x } catch (Exception $exception) { // Executed only in PHP 5.x, // will not be reached in PHP 7 }
  53. Tommy Mühle | tommy-muehle.io And now show 
 me some

    fancy stuff 52
  54. Tommy Mühle | tommy-muehle.io 53

  55. Tommy Mühle | tommy-muehle.io You send critical data to somebody

    else. 54
  56. Tommy Mühle | tommy-muehle.io 55 https://rollbar.com/demo/demo/

  57. Tommy Mühle | tommy-muehle.io 55 https://rollbar.com/demo/demo/ https://angel.co/bugsnag/jobs

  58. Tommy Mühle | tommy-muehle.io 55 https://rollbar.com/demo/demo/ https://angel.co/bugsnag/jobs https://www.g2crowd.com/products/raygun-crash-reporting/details

  59. Tommy Mühle | tommy-muehle.io 56

  60. Tommy Mühle | tommy-muehle.io Tommy Mühle | tommy-muehle.io 57 „Sentry

    is 100% open source. All features are built in the open and can be followed and contributed to on GitHub.“ https:/ /sentry.io/about
  61. Tommy Mühle | tommy-muehle.io 58 https://github.com/getsentry/sentry

  62. Tommy Mühle | tommy-muehle.io 59 https://hub.docker.com/_/sentry/

  63. Tommy Mühle | tommy-muehle.io Client usage 60

  64. Tommy Mühle | tommy-muehle.io 61 $sentryClient = new Raven_Client( 'https://<key>:<secret>@sentry.io/<project>'

    ); // or $sentryClient->install(); $error_handler = new Raven_ErrorHandler($sentryClient); $error_handler->registerExceptionHandler(); $error_handler->registerErrorHandler(); $error_handler->registerShutdownFunction();
  65. Tommy Mühle | tommy-muehle.io 62 $sentryClient->captureException($exception, [ 'extra' => [

    'php_version' => phpversion(), 'foo' => 'bar', // ... ], 'logger' => 'default', 'tags' => ['key' => 'value'], // group event by 'fingerprint' => ['{{ default }}', 'other value'], ]);
  66. Tommy Mühle | tommy-muehle.io 63

  67. Tommy Mühle | tommy-muehle.io 64

  68. Tommy Mühle | tommy-muehle.io 65

  69. Tommy Mühle | tommy-muehle.io 66

  70. Tommy Mühle | tommy-muehle.io 67

  71. Questions?

  72. Thank you! Slides http:/ /bit.ly/2kzZkjx Images https:/ /pixabay.com/ @tommy_muehle