MVC Pattern – How to Get Errors from the Model to the Controller

mvcobject-orientedobject-oriented-designvalidation

Say I have a typical MVC setup. The controller passes on some input to the model, and asks it to do something with it. But the validation of the data fails, or there is some other problem. What's the best way of getting these errors passed back to the controller, which will then pass them to the view to be displayed to the user?

At the moment, I just have an errors array in my model. When any errors occur, I simply add the error messages to this array, and return false to the controller, so it knows that errors occurred. And in the controller, I do this:

boolean result = model.process( input );

if (! result)
{
   view.displayErrors( model.getErrors() );
   return;
}
else
   view.displaySuccess();

Is there a better way of handling this?

Best Answer

So what you're suggesting / currently doing is one method, and it's certainly a valid way of gathering additional information about error messages.

It's a reasonably lightweight approach - the caller gets a success | failure message and then it's up to the caller to dig deeper for additional information if it so cares. The downside is what you alluded to with the comments - what if there are multiple issues within the validation?

It wouldn't be too hard to extend this approach so that the caller loops over a GetErrorDetails() call until that method returns an indicator of "no more errors."

Another potential issue with this approach is the implicit assumption that the caller is in the best position to deal with whatever the error messages may be. Since you're using MVC, the controller isn't always the best layer to fix that problem. The validation errors need to be pushed back to the View so the user can correct the issue. I'm not focusing on this aspect since there are some valid counter-arguments to indicate that the Controller could / should indicate the error. That discussion is not the point of your question.

Altertnative 1
As an alternative, consider making a full blown object to return errors with. Instead of the boolean that you're currently returning, you'll return that error object instead.

Obviously, the error object will need to have a value to indicate success | failure | partial-success | whatever. The benefit is that you can now add a collection of errors within the error object itself.

Here's some pseudo-code to give you an idea of what I'm suggesting.

ErrorParent()
{
  bool success;
  List errorMsgs;
}

ErrorMessages()
{
  string message;
  int  severity;
  List callstack;
}

The caller has to work a little harder to determine success, but it's an equally simple ErrorParent.success check as opposed to a success check. Yes, yes, I know the troubles of typing out a few more characters...

If the caller cares about the errors, then it can iterate over the ErrorParent.errorMsgs collection and see what all went wrong. If the caller doesn't care about the errors then it can pass the error object off to an error handler and let the handler do all the hard work.

Alternative 2
Instead of returning a bool for success / error, you could return a numeric value. The numeric value would indicate the number of failed validations. The Controller could pass that numeric error return to the "best" error handler for that situation, and then the error handler would loop over the GetErrorDetails() method.

Related Topic