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

try { Getting People To Come To a Talk On Exceptions }

Ed van Beinum
February 20, 2012

try { Getting People To Come To a Talk On Exceptions }

Answering the 5 most important questions you have about Exceptions in PHP

Ed van Beinum

February 20, 2012
Tweet

Other Decks in Science

Transcript

  1. Getting People To Come To A
    Talk About Exceptions
    PHPUK February 2012
    try {
    }
    1

    View Slide

  2. Who the hell is this guy?
    Ed van Beinum
    Arsing about with PHP for about
    6 years
    @edvanbeinum
    http://www.edvanbeinum.com
    https://joind.in/talk/view/4959
    Slides: http://bit.ly/ed-loves-exceptions
    2

    View Slide

  3. Exceptions, eh? Wow that
    sounds really boring.
    3

    View Slide

  4. The 5 most important questions
    you have about Exceptions
    ★ What the hell is an Exception, really?
    ★ When should I throw an Exception?
    ★ Is there any PHP-specific craziness I should
    know about?
    ★ Why don’t some folk like Exceptions and
    what are the alternatives?
    ★ Are there any best practices when using
    Exceptions?
    4

    View Slide

  5. What the hell is an
    Exception, really?
    5

    View Slide

  6. Where did they come from?
    Upon failure, functions could do one of three
    things
    ★ output parameters
    ★ set a global error variable
    ★ return a value
    6 What the hell is an Exception, really?

    View Slide

  7. The problems with return values
    ★ How do you differentiate between normal
    values and error values?
    ★ (AKA the Semipredicate Problem)
    ★ No stacktrace, no message, no context
    ★ Dealing with multiple function calls soon gets
    messy
    ★ Violates Command Query Separation
    7

    View Slide

  8. Exceptions solve these
    problems
    8

    View Slide

  9. Can I get a definition?
    “Exceptions are specific means by which code can
    pass along errors or exceptional events to the code
    that called it”
    Code Complete 2,
    Steve McConnell
    9 What the hell is an Exception, really?
    an alternative channel

    View Slide

  10. I would hear this a lot
    “Exceptions are for unexpected events”
    The Pragmatic Programmer,
    Hunt & Thomas
    10 What the hell is an Exception, really?
    throw new
    ZombiesErruptFromSidewalkException;

    View Slide

  11. Let’s try that again
    “Exceptions are for incorrect circumstances”
    Just Now,
    Me
    11 What the hell is an Exception, really?
    throw new BicycleOnSidewalkException;

    View Slide

  12. When should I throw an Exception?
    12

    View Slide

  13. Robustness v Correctness
    ★ Correctness
    is it better that the application returns correct
    data
    ★ Robustness
    is it better that the application carries on
    functioning
    13 When should I throw an Exception?

    View Slide

  14. Not enough Context
    Can we fix it?
    Yes.
    // Snippet from Zend_Rest_Client
    public function setUri($uri)
    {
    if ($uri instanceof Zend_Uri_Http) {
    $this->_uri = $uri;
    } else {
    $this->_uri = Zend_Uri::factory($uri);
    }
    return $this;
    }
    14 When should I throw an Exception?

    View Slide

  15. Not enough Context
    Can we fix it?
    No.
    // Snippet from Zend_Rest_Client
    private function _prepareRest($path)
    {
    // Get the URI object and configure it
    if (!$this->_uri instanceof Zend_Uri_Http) {
    throw new Zend_Rest_Client_Exception('URI object
    must be set before performing call');
    }
    }
    15 When should I throw an Exception?

    View Slide

  16. // Snippet from Zend_Rest_Client
    public function setUri($uri) {
    if ($uri instanceof Zend_Uri_Http) {
    $this->_uri = $uri;
    }
    elseif ( ! is_numeric($uri)) {
    $this->_uri = Zend_Uri::factory($uri);
    }
    else {
    throw new Zend_Rest_Client_Exception('URI must be
    instance of Zend_Uri_Http or a String');
    }
    }
    Are we losing Context?
    Are we passing on an error down the call chain?
    16 When should I throw an Exception?
    // Snippet from Zend_Rest_Client
    public function setUri($uri)
    {
    if ($uri instanceof Zend_Uri_Http) {
    $this->_uri = $uri;
    } else {
    $this->_uri = Zend_Uri::factory($uri);
    }
    }

    View Slide

  17. Are Exceptions being used for flow control?
    “...ask yourself “Will this code still run if I remove all
    the exception handlers?” If the answer is “no” then
    you maybe exceptions are being used in non-
    exceptional circumstances”
    The Pragmatic Programmer
    try {
    $this->getUser();
    }
    catch (UserNotLoggedInException $e) {
    $this->redirect('/login');
    }
    17 When should I throw an Exception?

    View Slide

  18. Terminate?
    “Am I prepared to end the program?”
    Exceptional Ruby,
    Avdi Grimm
    18 When should I throw an Exception?
    ★ Uncaught exceptions will terminate your
    program

    View Slide

  19. Are you writing a library?
    19 When should I throw an Exception?

    View Slide

  20. Is there any PHP-specific craziness I
    should know about?
    20

    View Slide

  21. Yes.
    21

    View Slide

  22. Lots.
    22

    View Slide

  23. PHP: Errors v Exceptions
    Oh PHP is quirky. And bears defecate in wooded areas.
    ★ It has Exceptions
    ★ It has return codes
    23 Is there any PHP-specific craziness I need to know about?

    View Slide

  24. PHP: Errors v Exceptions
    It has something else too
    ★ Errors
    24 Is there any PHP-specific craziness I need to know about?

    View Slide

  25. PHP: Errors v Exceptions
    One more thing...
    ★ If there are problems with POST upload...
    $_FILES['fileFieldName']['error'];
    25 Is there any PHP-specific craziness I need to know about?

    View Slide

  26. Well, that sounds
    confusing
    26 Is there any PHP-specific craziness I need to know about?

    View Slide

  27. As a rule of thumb
    ★ Exceptions are thrown by
    ★ Us the programmer
    ★ The newer PHP5 components (PDO,
    DateTime, Sqlite, etc)
    ★ Errors are ‘triggered’ by the older procedural
    PHP core functions
    ★ Return values are returns from core
    functions when a non-exceptional event
    occurs
    27 Is there any PHP-specific craziness I need to know about?

    View Slide

  28. How to deal with Errors
    There are many functions that allow the
    programmer to interact with Errors
    set_error_handler('newErrorHandler');
    restore_error_handler();
    28 Is there any PHP-specific craziness I need to know about?

    View Slide

  29. protected function _loadFileErrorHandler($errNo, $errStr,
    $errFile, $errLine)
    {
    $this->_errorStr = $errStr;
    }
    protected function _parseIniFile($filename) {
    set_error_handler(array($this, '_loadFileErrorHandler'));
    restore_error_handler();
    if ($this->_errorStr !== null) {
    throw new Zend_Config_Exception($this->_errorStr);
    }
    }
    29 Is there any PHP-specific craziness I need to know about?
    $iniArray = parse_ini_file($filename, true);
    How Zend Framework deals with Errors

    View Slide

  30. Other PHP ‘fun’
    die(); exit();
    If you post a tutorial on the internet about how to
    connect to a database you simply must use this.
    Please stop.
    ★ No context other than the string it was
    passed
    ★ Terminates immediately
    ★ Better to use Exceptions
    30 Is there any PHP-specific craziness I need to know about?

    View Slide

  31. @
    31

    View Slide

  32. The horror.
    32

    View Slide

  33. The Suppression Operator
    // something might go wrong but I don't know what to
    do about it
    @$zombie->reanimate();
    ★ The Suppression Operator sets ERROR_REPORTING
    to 0 executes the given function then reverts
    ERROR_REPORTING to its previous setting.
    ★ If a fatal Error occurs during the suppressed
    function, the program will terminate with no
    indication why.
    33 Is there any PHP-specific craziness I need to know about?

    View Slide

  34. SPL Exceptions
    Woo! But we forgot to document them.
    Exception
    LogicException
    BadFunctionCallException
    BadMethodCallException
    DomainException
    InvalidArgumentException
    LengthException
    OutOfRangeException
    RuntimeException
    OutOfBoundsException
    OverflowException
    RangeException
    UnderflowException
    UnexpectedValueException
    34 Is there any PHP-specific craziness I need to know about?

    View Slide

  35. Why don’t some
    folk like
    Exceptions and
    what are the
    alternatives?
    35

    View Slide

  36. Potential Problems
    ★ Invisible in the source code
    PHP has no throws keyword we must rely on
    @throws annotation or code inspection
    36 Why not Exceptions and what are the alternatives?

    View Slide

  37. Potential Problems
    ★ Create more paths through a function
    More complexity = more bugs
    "An Exception represents an immediate nonlocal
    transfer of control - it's a kind of cascading goto"
    The Pragmatic Programmer
    37 Why not Exceptions and what are the alternatives?

    View Slide

  38. Potential Problems
    ★ Coupling
    Zend_Exception anyone?
    38 Why not Exceptions and what are the alternatives?

    View Slide

  39. Potential Problems
    ★ Weakens encapsulation
    39 Why not Exceptions and what are the alternatives?

    View Slide

  40. So what are the Alternatives?
    40 Why not Exceptions and what are the alternatives?

    View Slide

  41. Good Enough data
    If your application requires robustness over
    correctness then return 'good enough' data
    ★ Closest legal value
    ★ The next/previous piece of valid data
    ★ Neutral value
    41 Why not Exceptions and what are the alternatives?

    View Slide

  42. Null Object
    $zombie = NoveltyOrm::getZombie($name);
    ?>
    Human Name:

    Infection Date:

    42 Why not Exceptions and what are the alternatives?

    View Slide

  43. No-Raise API
    “In most cases the caller should determine how to
    handle an error not the the callee”
    The Practice of Programming,
    Kernighan & Pike
    43 Why not Exceptions and what are the alternatives?

    View Slide

  44. No-Raise API
    PHP’s cURL library does this.
    $ch = curl_init();
    curl_setopt(
    $ch, CURLOPT_URL, "http://en.wikipedia.org/wiki/Zombie"
    );
    $result = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($httpCode == 418) {
    throw new TeapotException();
    }
    44 Why not Exceptions and what are the alternatives?

    View Slide

  45. Defensive Programming
    Every other programmer is an idiot
    45 Why not Exceptions and what are the alternatives?

    View Slide

  46. Design By Contract
    Came from Eiffel
    DbC allows the programmer to define what is
    correct circumstances
    ★ pre-conditions: must be true for routine to
    work correctly
    ★ post-conditions: will be true after routine has
    worked correctly
    46 Why not Exceptions and what are the alternatives?

    View Slide

  47. So what about PHP?
    ★ PHP has an assert() function since PHP4
    class Human{}
    class Zombie{}
    function eliminate($target) {
    assert('$target instanceof Zombie');
    }
    eliminate(new Human);
    ★ But... it uses errors. Yuck.
    // PHP Warning: assert(): Assertion "$target
    instanceof Zombie" failed in zombie.php on line 6
    47 Why not Exceptions and what are the alternatives?

    View Slide

  48. So what about PHP?
    Checkout Stuart Herbert's ContractLib
    ★ No eval'ed strings
    ★ Throws Exceptions
    https://github.com/stuartherbert/ContractLib
    48 Why not Exceptions and what are the alternatives?

    View Slide

  49. Are there any best practices
    when using Exceptions?
    49

    View Slide

  50. Empty Catch block
    Either a problem in try {} block:
    ★ Why is it throwing an Exception for an
    unexceptional circumstance?
    Or a problem in the catch():
    ★ Why doesn’t it handle the Exception?
    50 Are there best practices when using Exceptions?

    View Slide

  51. Subclassing Exceptions
    What’s the point?
    ★ Add context
    ★ You catch an Exception based on class
    ★ Not solely reliant on the Exception's message
    to provide information
    ★ Avoid namespace clashes if two libraries both
    throw \exception()
    51 Are there best practices when using Exceptions?

    View Slide

  52. Subclassing
    try {
    $olfactoryLib->detectBrains();
    $motionLib->stumbleForward();
    } catch (Exception $e) {
    // wait, which library threw that?
    }
    52 Are there best practices when using Exceptions?

    View Slide

  53. Subclassing
    try {
    $olfactoryLib->detectBrains();
    $motionLib->stumbleForward();
    } catch (OlfactoryLib_BrainsNotFoundException $e) {
    // rotate 90 degrees, retry
    } catch (MotionLib_ShoppingMallDoorBarricadedException
    $e) {
    // groan, press up against glass and wait
    }
    53 Are there best practices when using Exceptions?

    View Slide

  54. Appropriate Abstraction Level
    Watch out, it is quite easy to expose
    implementation details through Exceptions
    try {
    $human->getBrains();
    } catch (FileNotFoundException $e) {
    error_log($e->getMessage());
    }
    54 Are there best practices when using Exceptions?

    View Slide

  55. Finally...
    Exceptions:
    ★ Alternative communication channel for
    incorrect circumstances
    Before throwing them:
    ★ 'Are you prepared to end the program?'
    The crazy world of PHP failure handling
    Think about the alternatives
    Best practices
    55

    View Slide

  56. End
    56
    Thank you to my 'proof listeners' Ian Barber, Paul Matthews and Alistair Stead

    View Slide

  57. Further Reading
    Exceptional Ruby - Avdi Grimm
    Code Complete 2 - Steve McConnell
    The Pragmatic Programmer - Hunt & Thomas
    The Practice of Programming - Kernighan & Pike
    Exceptional PHP : Introduction To Exceptions - Brandon Savage
    How to use SPL Exception Classes - Jani Hartikainen
    Exceptions - Joel Spolsky
    Should a failed function return a value or throw an exception? - Jani Hartikainen
    Error codes or Exceptions? Why is Reliable Software so Hard? - Damien Katz
    Exception Best Practices in PHP 5.3 - Ralph Schindler
    57

    View Slide

  58. Further Reading
    Pear2 Exception Policy
    Comparing ContractLib to PHP's assert() - Stuart Herbert
    Design by Contract in PHP with Assertions - Luke Maciak
    Return False with prudence - David Winterbottom
    What are the principles guiding your exception handling policy? -
    Stackoverflow
    Effiel Presentations
    58

    View Slide

  59. Thank you for daft zombie pictures
    http://www.flickr.com/photos/silencedpp7/6721932955/in/[email protected]/
    http://www.flickr.com/photos/scottjacksonx/3838449067/in/photostream/
    http://www.flickr.com/photos/mickythepixel/6053021490/sizes/l/in/photostream/
    http://www.flickr.com/photos/davidrcrowe/4996097258/sizes/l/in/photostream/
    http://www.examiner.com/zombie-in-denver/roadside-sign-boulder-warns-zombies-ahead-this-morning
    http://www.freshbooks.com/blog/2011/10/31/costume-contest-11-vote-for-your-favourite/
    http://www.splitreason.com/product/354
    http://survival.outdoorlife.com/photos/gallery/survival/2010/03/surviving-undead-zombie-guns?
    photo=1
    http://www.flickr.com/photos/dunechaser/2629616053/
    http://www.flickr.com/photos/dunechaser/2816913800/
    http://www.thezombienation.com/2011/02/19/a-rubiks-cube-for-zombies/
    59

    View Slide