We all agree that using different exception types for different tasks is the way to go.
But then, we end up with creating ghost files like this:
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Dojo
* @subpackage View
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Dojo_Exception
*/
require_once 'Zend/Dojo/Exception.php';
/**
* @category Zend
* @package Zend_Dojo
* @subpackage View
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Dojo_View_Exception extends Zend_Dojo_Exception
{
}
Then the same for Zend_Dojo_Exception and the same for Zend_Exception…
Is there any generic approach for this problem?
Something like throw new \My\Just\Declared\Exception\ (which extends \My\Just\Exception), so I didn’t have to crate and require all those ghost files?
In good practice, not really… There are however some hacks you could do if you REALLY wanted to do this, but I still think they are more evil.
For example, one of those hacks is to
evalthose classes into existance via an autoloader. This is bad because if someone evergreps for the exception’s definition or for the exceptions that your package throws they are going to be a whole lot of nada in return…But again, let me stress this is usually a bad idea.
Personally, I inherit from multiple “base exceptions” (typically the
SPLexceptions). So for example aDatabase_Connection_Exceptionmight extendRuntimeException, trying to commit a non-open transaction might throw aDatabase_Not_In_Transaction_Exceptionwhich might extendLogicException. The point being that declaring them separately lets you do more than just straight heiarchal inheritance (not to mention is better for documentation, since people can look at a glance at the defined exceptions, and you can actually override methods to better suit your needs if appropriate)…Edit: Based upon your mention of
Zend‘s tendency to do one exception per sub-package, here’s how I do it…Basically, I have a few “global” exceptions that are used throughout the application(s). These include (but are not limited to):
ClassNotFoundException,FileNotFoundException,NotCallableExceptionand a bunch of others. Basically just those that aren’t package specific, but need to convey more meaning than the core PHP exceptions can…Then, I declare exceptions on a package level only. In that directory (
package/exceptions) I declare each and every exception as necessary. So one subpackage may have 5 or 10 exceptions to distinguish different conditions, while another subpackage (within the same package) may have none. So I declare them as needed so that the exception means what happened.I do this for a simple reason. I don’t care about
wherethe exception was thrown from (And if I really did, I can inspect the backtrace that’s automatically generated inside of the exception). I care aboutwhythe exception was thrown. And that lets me properly handle the exception…