CakePHP and error/exception handling

Copyright CakePHP

I’m currently using CakePHP and finding it to be quite useful. The “automagic” handling of tables is useful for basic relationships, though more complicated setups usually require manual work. The MVC implementation has also clearly drawn inspiration from Ruby on Rails, which may be advantageous to some, though this has no bearing on me. Though there are a few things that nag me about CakePHP (such as lack of a good testing suite, though that’s supposedly fixed in 1.2, which really should be marked as version 2.0), overall it’s a great framework that adds badly-needed structure to PHP and has saved me time.

One thing I’d like to see, however, is a proper exception handling model. I realize this would require making it PHP 5-only, but in my opinion, PHP 5 adds some sorely-need features, such as the aforementioned exception handling model and a class/object system more in line with other languages.

Signaling intent

I’ve written about the benefits of exception handling before, so I won’t delve into those details again. In short, using exceptions is a better way for a method to signal to a caller that something went wrong rather than just returning a special/reserved value as an error code.

In particular, saving of models would benefit from this. Currently, if you want to check if the model was saved properly, you have to do something like this:

if ($this->ModelName->save($this->data))
  // Model saved properly, can continue normally here.
 // Model did not save properly.

It’s a little bit kludgy, but isn’t actually that bad since Cake simplifies form validation a lot with the HTML helper in views. You can simply put something like $html->tagErrorMsg('Post/title', 'Title is required.') in your view to display that error message when a particular field does not validate. This removes a lot of the tedium out of making your forms return proper error messages in situations with bad input.

Exceptional cases

However, in some situations you might want to execute your own logic when a call to Model::save() fails. In this case, having that method throw a proper exception would allow the error to be propagated to the controller nicely and would remove the need to make a call to Model::invalidFields() to get the reason.

Coming from a Java background, this makes more sense to me, since I consider its exception handling model to be one of the language’s strong points. It has numerous benefits to improving readability and maintainability of code.

However, there are some drawbacks, since this requires the use of PHP 5. As CakePHP is designed to be PHP 4 and 5 compatible, exception handling is really not an option. However, since PHP 4 is so old, I’d eventually like to see a move to PHP 5, especially for its better OOP model and exception handling. Additionally, PHP 6 is just around the corner, so I don’t really see a need to stick with PHP 4 for that much longer.

Additionally, if you’re just saving one model (as the result of a form submission) it doesn’t really make sense, nor is it necessary, to have exception handling since CakePHP already takes care of displaying error message for the invalid fields:

// Controller:
if ($this->Post->save($this->data))
  $this->flash('Your post has been saved.','/posts');

// View:
<?php echo $html->input('Post/title', array('size' => '40'))?>
<?php echo $html->tagErrorMsg('Post/title', 'Title is required.') ?>

In the above example, taken from CakePHP’s own blog tutorial, you don’t really need exception handling since the appropriate actions are automatically handling by Cake. If the save succeeds, a positive message will be displayed and the user forwarded on. Otherwise, the controller proceeds to render the given view, where $html->tagErrorMsg displays the given error message if the associated field was marked as invalid by the model during the save attempt.

For more complicated situations where you’re saving multiple related models in a single controller action, exception handling would be helpful in reducing the number of branches, since you wouldn’t need to have so many if ... else blocks muddling up the flow of the code. However, it’s not straightforward to integrate this into Cake, since for most of the time, people won’t need the exception handling capability if they’re just doing a simple save as outlined above.

The easiest way I see of accomplishing this is to define your own method that wraps around the existing Model::save() method so that proper exceptions can be thrown. This would, of course, create confusion as then there would be two ‘save’ methods.

All things considered, Cake is still a strong framework, so I will continue using it. For all the slight concerns I have, it’s still very much beneficial to me. If there’s one more thing I could ask for from Cake though, it would be for better documentation! Maybe I should start contributing…

One Comment »

  1. Nice article. I will love to read more post related to cakephp as I am a newbie.

Comments are now closed for this entry.