Custom Exceptions in Magento


Magento comes with a number of Exceptions out of the box but more often than not, Magento’s core code will throw either just a basic PHP Exception or a Mage_Core_Exception, in fact, in /app/Mage.php the method throwException, which is used throughout the code base, simply throws a Mage_Core_Exception.

Sometimes a basic Exception just isn’t specific enough to catch the problem responsibly so you can deal with the issue. If you’re writing a custom module and you tend to wrap your code in try and catch blocks, convention would insist you use Mage::throwException(), directly throw a Mage_Core_Exception or just a basic Exception. However, these Exceptions only give you a message to explain the error and you can’t type hint reliably against a message string.

Why should I type hint my catch blocks

Type hinting your catch blocks with specific Exceptions allows you to deal with each specific issue separately, for instance, if you are saving a blog post which must also update your Twitter account you might have something like this in your controller action:

class StudioForty9_Mymodule_Controller_Blog extends Mage_Core_Controller_Front_Action
{
	...
	public function saveAction()
	{
		$post = new Varien_Object();
		$post->setData($this->getRequest->getPost());
		
		try {
			$this->_validateData($post);
			$this->_saveBlog($post);
			$this->_notifyTwitter($post);
		}
		catch (StudioForty9_Mymodule_Model_Blog_ValidationException $e) {
			// e.g. set a 'validation' error message on the session
		}
		catch (StudioForty9_Mymodule_Model_Blog_SaveException $e) {
			// e.g. set a 'unable to save' error message on the session
		}
		catch (StudioForty9_Mymodule_TwitterConnectionException $e) {
			// e.g. set a 'unable to connection' error message on the session
		}
		catch (StudioForty9_Mymodule_TwitterPermissionException $e) {
			// e.g. set a 'invalid twitter permission' error message on the session
		}
		catch (Exception $e) {
			Mage::logException($e)
			// e.g. set a 'unknown error' error message on the session
		}
		
		return $this->_redirect('*/*/');
	}
	...
}

In the above code snippet, there’s quite a bit going on and it reflects a certain method of programming, rather than checking the return value of every method and running a conditional to verify that the value is what you expect before moving on, we write exactly what the code is doing in one self-contained area and we handle the possible issues as they come up, of course you can still run conditionals inside of the try block if you need to and that’s fine but the ultimate goal of coding in this style is to make your code as simple to comprehend as possible.

Custom Exceptions in Magento

Hopefully you’ll agree that the above is a pretty clean approach to writing code but you might be wondering, where do I put these custom Exceptions? You don’t want to clutter up your Model, Controller, Block or Helper classes by stuffing the custom Exception class in above or below them. Remember, each class should have it’s own file and Exceptions are no different. But there’s no Exceptions folder in the Magento structure, how will Magento know how to load my custom Exception class? I don’t want to have to require_once every time I need to use my custom Exception.

Lazy Loading Custom Exceptions

Luckily, Magento has your back, though you might not have guessed it. Let’s say you’ve created your own blog model class and you want to create a custom exception for that model. You can just put that custom exception in your model directory and Magento will load it for you. For example, if you have a model StudioForty9_Mymodule_Model_Blog and you want to create a custom Exception for that model StudioForty9_Mymodule_Model_Blog_SaveException, you could create the file under app/code/local/StudioForty9/Mymodule/Model/Blog/Exception.php. You could do the same for Helpers, Blocks and even Controllers if you wish.

Sometimes, however, even using those typical Magento folders aren’t always quite right, what if your custom exception can be used by any of your custom classes, a Controller, Model, Helper, Block etc. You can actually put that Exception in the Module’s root folder. So, given the module name from the example above, StudioForty9_Mymodule_TwitterConnectionException would be your Exception class name and the path would be app/code/local/StudioForty9/Mymodule/TwitterConnectionException.php

I couldn’t find much direction on custom exceptions online so I researched the situation a bit and thought I’d share my findings in the hope that it might help someone else, happy coding and feel free to comment below!

Ted Robinson
Ted Robinson |