Re: Re: PEAR2 Standards Update

From: Date: Tue, 22 Sep 2009 18:54:27 +0000
Subject: Re: Re: PEAR2 Standards Update
References: 1 2 3  Groups: php.pear.dev php.standards 
Request: Send a blank email to pear-dev+get-52887@lists.php.net to get a copy of this message
On Tue, Sep 22, 2009 at 12:47 PM, Michael Gauthier <mike@silverorange.com>wrote: > On Tue, 2009-09-22 at 18:42 +0200, till wrote: > > On Tue, Sep 22, 2009 at 5:38 PM, Brett Bieber <brett.bieber@gmail.com> > wrote: > > > Greetings everyone - > > > > > > Just an update on PEAR's progress adopting the "PHP Standards and Best > > > Practices for PHP 5.3+ Frameworks and Libraries." :-) > > > > > > At the last PEAR Group meeting the exception policy and the class > > > naming policy were approved by the PEAR Group and are now incorporated > > > into the PEAR2 standards. > > > > I got a couple questions -- and I looked at the docs. > > > > Currently, a couple packages implement/use SPL exceptions directly, > > e.g. they throw an InvalidArgumentException and not > > Foo_InvalidArgumentException. Does this mean we have to wrap all SPL > > exceptions when we want to use them? > > > > Also, how exactly does that play with having a base exception class? > > > > My base exception class is Foo_Exception, but I want to use SPL > > exceptions as well. How do I extend to conform to the rule to provide > > one base exception for the package? From what it looks like, I extend > > the SPL exception but implement my own package' base exception. I'm > > not sure if I read the code right, so I'm asking to make sure. > > You are required to wrap SPL exceptions thrown by your package. The idea > here is that all exceptions generated by a package can be caught using > "catch foo\Exception $e". > > For example: > > class foo\InvalidArgumentException extends \InvalidArgumentException > implements foo\Exception > { > } > > Cheers, > > > Mike > I think this below sets up the strongest use case -- let's consider this set of base package exception classes: - class \foo\Exception extends \Exception {} - class \foo\InvalidArgumentException extends \InvalidArgumentException {} - class \foo\OutOfBoundsException extends \OutOfBoundsException {} Let's say I'm a package user who is only interested in catching this package's exceptions generically, not trying to specifically watch for each type of exception that the package could possibly throw. This means I want the ability to catch them all from one *catch()* clause. Now, how can I catch all three of these package exceptions above with one *catch()*? The only way would be to *catch(\Exception)*, the global Exception, because that's the only common parent class, right? \foo\InvalidArgumentException doesn't extend from \foo\Exception, so *catch(\foo\Exception)* would not catch it... the same applies to \foo\OutOfBoundsException. I know that someone is going to think of "I could just *try {} catch(\foo\Exception) {} catch(\Exception) {} *, but that's requiring the package user to catch *everything*, not just exceptions from the package alone. If you go with the base exception class along with exceptions extending from SPL, then the only way the package user can catch "only the package exceptions" is to explicitly catch every single type that you define in your package. The standard says to define them this way: - interface \foo\Exception {} - class \foo\InvalidArgumentException extends \InvalidArgumentException implements \foo\Exception {} - class \foo\OutOfBoundsException extends \OutOfBoundsException implements \foo\Exception {} Now, *catch(\foo\Exception)* could indeed catch both of those package exceptions above. A smaller edge case rationale for going with an interface instead is the intersection of: - user of package decides to subclass the package's exceptions - maintainer of package decides to refactor the package's exceptions This sets up a potential BC break, if you remove/modify your package's exception classes at all. It boils down to being a safety net for the benefit of the users of your package, I think. I'm putting together a concrete code example, which I'll pass on shortly... -- CRB

« previous php.pear.dev (#52887) next »