0

I'm trying to develop a personal MVC framework for learning purposes. But every time I'm stuck in this problem: errors.

I feel like I'm handling them very bad. Currently I have an exception system (everything is converted to exception, even PHP triggered errors) that is catch in a try{} block that contains every line of code of the framework and the user application.

I'm treating errors such as "controller not found" or "action not found" like any other, for example "unable to connect to the database". But I feel like the latter is somehow more an "exception" rather than a pretty common "controller not found (404)".

Also currently I'm using an error handling that pretty much copy the way MVC works in my framework, in the sense that when an error occurs I load a specific action and load a specific view file for each type of error. I'm not using the MVC (by MVC I mean all the mechanism that load a controller, run an action, load a model and views for the user application) of my framework because an error in the MVC could cause an error to be triggered, which would try to manage it with the MVC which would trigger the same error again and then the MVC to be loaded again and so on in an infinite loop.

How should I handle every error of my framework? What are the best practice right now?

Yi Jiang
  • 46,385
  • 16
  • 133
  • 131
Shoe
  • 70,092
  • 30
  • 150
  • 251
  • 1
    You might find this a very useful post: [Error logging, in a smooth way](http://stackoverflow.com/questions/10331084/error-logging-in-a-smooth-way) – tereško Jun 16 '12 at 14:09

2 Answers2

2

The execution of controller IMHO can generate two exceptions:

  • not found: when controller or method is missing
  • permission denied: when ACL blocked access

To handle this, i would just go with something like following code. And you can use multiple catch block.

try
{
    $controller->$command($request, $response);
}
catch(AccessDeniedException $e)
{
    $controller = new ErrorController;
    $controller->accessDenied($request, $response);
}
catch(NotFoundException $e)
{
    $controller = new ErrorController;
    $controller->notFound($request, $response);
}

You can let AccessDeniedException to bubble up from Model Layer too, but usually it is a bad practice. Exception should be handles within same level of abstraction, where it was thrown, or, in case of critical exceptions (when object itself is unable to deal with it), the exceptions might penetrate ONE abstraction boundary. And exceptions should NOT leave the Model Layer, instead they should create error state in the layer, and be processed in your current View instance.

The point is this: instead of magical handler for all errors, you should handle errors close to the place where it originated.

Community
  • 1
  • 1
tereško
  • 56,151
  • 24
  • 92
  • 147
  • Multiple `catch` blocks work fine, what makes you think that they don't? See [Extending exceptions](http://uk.php.net/manual/en/language.exceptions.extending.php) – Alan Pearce Jun 16 '12 at 14:40
  • @Alan , tnx .. a quick search gave me the impression, that it was not possible – tereško Jun 16 '12 at 14:41
  • The code for every exception that may occur is always the same: render an HTML div that shows the error and stop executing. – Shoe Jun 16 '12 at 16:17
  • @Jeffrey , so basically what you are saying is: **tl;dr** – tereško Jun 16 '12 at 16:34
  • @tereško, I didn't got what you were saying the first time. Ok, you solution for not-found and access-denied errors is ok. What about if an error occurs in `ErrorController`? – Shoe Jun 16 '12 at 16:53
  • @Jeffrey , there is a difference between error an exception. If an you get `E_ERROR` anywhere, then it's already too late. It gets passed off to [error handler](http://uk.php.net/manual/en/ref.errorfunc.php), which prints the message and exits. If error controller throws an exception, then too something has gone horribly wrong and goes to global error handler. – tereško Jun 16 '12 at 17:03
0

You can do something like a more proper message at the try catch. For example:

try
{
    //Your code here
}
catch (Exception $e)
{
    // Clean the output buffer if one exists
    ob_get_level() and ob_clean();

    // Display the exception text
    echo sprintf('%s [ %s ]: %s ~ %s [ %d ]', get_class($e), $e->getCode(), strip_tags($e->getMessage()), $e->getFile(), $e->getLine())."\n";

    // Exit with an error status
    exit(1);
}
John Skoumbourdis
  • 2,651
  • 19
  • 25
  • Is it not better to display a friendly error message to the user and log the Exception? IMO, a user should not see a technical message that in most cases would not mean anything to them. – Haroon Jun 16 '12 at 13:45
  • For the user you can insert an if there and have a message like this: "Something went wrong, please try again later. The administrator of the system has already informed about this error and will fix it soon. If thought you still see this message you can contact for this error with issue number 432918702394870123984701". There you can store it to log files,database or even send an email to you. You can handle with any way you want there is not a standard way to do it. – John Skoumbourdis Jun 17 '12 at 18:30