I want to create a custom Magento exception class for my module.
Are there any rules for how I should do it? Where should I put the new class? How should it be thrown?
I'm familiar with Mage::throwException()
, should it be done like that?
Are there any rules for how I should do it?
Yes. If you take a look at app/Mage.php
in the exception()
method, you will see that it looks for an exception that matches the pattern $module . '_Exception
, for example: YourCompany_YourModule_Exception
:
/**
* Return new exception by module to be thrown
*
* @param string $module
* @param string $message
* @param integer $code
* @return Mage_Core_Exception
*/
public static function exception($module = 'Mage_Core', $message = '', $code = 0)
{
$className = $module . '_Exception';
return new $className($message, $code);
}
Where should I put the new class?
Because of the way this method works you have no control over where your exception is placed - it must be placed in the module root directory, and it must be named MyCompany_MyModule_Exception
. For example:
# File: app/code/local/MyCompany/MyModule/Exception.php
class MyCompany_MyModule_Exception extends Mage_Core_Exception
{
}
This is the way it is because the Magento autoloader will work the same way it does for other Magento classes in that it looks for an Exception
file in the MyCompany/MyModule
folder.
How should it be thrown?
Use the exception()
method instead of throwException()
. The former will throw an exception from a custom module, whereas the latter will throw a Mage_Core_Exception
:
if (false === $myResult) {
throw Mage::exception('YourCompany_YourModule', 'My result was false');
}
Catch:
try {
$this->doSomething();
} catch (YourCompany_YourModule_Exception $ex) {
var_dump('Caught custom exception:' . $ex->getMessage());
}
A side note, if you want to make your exceptions more specific to certain parts of your module, e.g. a certain Model, you can create Exception classes and put them whereever you want, as long as they follow the correct Magento naming convention for a class. You wouldn't use the method above to throw them however, you'd just have to throw them the old fashioned way:
# File: app/code/local/YourCompany/YourModule/Model/Connector/Exception.php
class MyCompany_MyModule_Model_Connector_Exception extends Mage_Core_Exception
{
}
Then throw it like this:
throw new YourCompany_YourModule_Model_Connector_Exception('The connection broke.');