Can a controller catch an exception thrown from a model?

Well, this is technically possible, but will it ruin the MVC architecture?

I am not sure if this type of communication is recommended between the controller and the model. I will describe it with a simple example and two ways to do this:

OPTION 1 (exception of model exceptions and the controller catches it):

class Controller { private $model; public function save($data) { try { $this->model->save($data); } catch (Exception $e) { // handle exception } } } class Model { public function save($data) { // Call to internal function to save data in BD if (! $this->_save($data)) throw new Exception('Error saving data'); } } 

OPTION 2 (the controller handles the exception completely):

 class Controller { private $model; public function save($data) { try { if (! $this->model->save($data)) throw new Exception('Error saving data'); } catch (Exception $e) { // handle exception } } } class Model { public function save($data) { // Call to internal function to save data in BD if (! $this->_save($data)) return false; } } 

**

EDIT after some answers:

**

These are other ways to solve this problem based on your suggestions. I hope this is not too difficult.

OPTION 3 (the model handles the exception completely, as Ray said. KingCrunch also suggested a better way to do this in the model)

 class Controller { private $model; public function save($data) { if (! $this->model->save($data)) { // possible action: redirect to the form with an error message } } } class Model { public function save($data) { try { if (! $this->_save($data)) throw new Exception('Error saving data'); } catch (Exception $e) { // handle exception return false; } return true; } } 

OPTION 4 (the controller receives a custom child exception generated by the model, as shiplu.mokadd.im said).

 class Controller { private $model; public function save($data) { try { $this->model->save($data); } catch (Exception $e) { if ($e instanceof ValidationException) { // handle validation error } elseif ($e instanceof DBStorageException) { // handle DB error } } } } class Model { public function save($data) { if (! $this->_validate($data)) { throw new ValidationException ('Validation error'); } if (! $this->_save($data)) { throw new DBStorageException ('Storage error'); } } } 
+8
php exception model-view-controller controller model
source share
3 answers

A model can throw an Exception and a Controller or View to catch it . Otherwise, you never know if everything works fine there. Therefore, use the first option. But make sure that you select the correctly abstracted exception that makes sense for the controller and View .

To illustrate in bold, look at these two throw statements that are used inside the model.

  throw new Exception('SQL Error: '.$mysqli->error()); // dont use it throw new DuplicateFieldException('Duplicate username'); // use this 

The second example does not display an internal error. Rather, he hides it. The controller should never know what is going on inside.

In your code, you have bound one model to one controller. The controller is not a single model. He is using a model. And he can use any number of models. Therefore, do not bind one model to the controller with a variable, like private $model .

+5
source share

Definitely the first option. Some words:

  • This is the task of the controller ... well, control. This means that you should make sure that at least a useful error message appears. Other parts of the application may do this sooner when they can handle an exceptional case. This includes the model itself: if it can handle it, it must do it.

  • save() means save. Do not abuse the return value for status information. When a method cannot save() , this is an exception, and when a method should not give you something, it should not give you something.

+2
source share

I prefer option 3.

The model should catch an exception, try to resolve it, if not push it to the controller, but only if this is what the controller could solve and recover. In this case (some error with saving the database), catching it in the returned model false , there should be an adequate resolution for the saving error and provide enough for the Controller to know that something went wrong when you save.

The controller does not need to worry about the implementation details of how the model implements persistence.

+1
source share

All Articles