Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Exceptions, eh? Wow that sounds really boring. 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

What the hell is an Exception, really? 5

Slide 6

Slide 6 text

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?

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Exceptions solve these problems 8

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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;

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

When should I throw an Exception? 12

Slide 13

Slide 13 text

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?

Slide 14

Slide 14 text

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?

Slide 15

Slide 15 text

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?

Slide 16

Slide 16 text

// 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); } }

Slide 17

Slide 17 text

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?

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Yes. 21

Slide 22

Slide 22 text

Lots. 22

Slide 23

Slide 23 text

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?

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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?

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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?

Slide 28

Slide 28 text

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?

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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?

Slide 31

Slide 31 text

@ 31

Slide 32

Slide 32 text

The horror. 32

Slide 33

Slide 33 text

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?

Slide 34

Slide 34 text

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?

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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?

Slide 37

Slide 37 text

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?

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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?

Slide 42

Slide 42 text

Null Object

Human Name:

Infection Date:

42 Why not Exceptions and what are the alternatives?

Slide 43

Slide 43 text

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?

Slide 44

Slide 44 text

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?

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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?

Slide 47

Slide 47 text

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?

Slide 48

Slide 48 text

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?

Slide 49

Slide 49 text

Are there any best practices when using Exceptions? 49

Slide 50

Slide 50 text

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?

Slide 51

Slide 51 text

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?

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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?

Slide 54

Slide 54 text

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?

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

Thank you for daft zombie pictures http://www.flickr.com/photos/silencedpp7/6721932955/in/pool-1121293@N25/ 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