管理框架的错误


Manage the errors of a framework

我正在尝试开发一个用于学习目的的个人MVC框架。但每次我都陷入这个问题:错误。

我觉得我处理得很糟糕。目前我有一个异常系统(所有内容都转换为异常,甚至是 PHP 触发的错误),它在一个 try{} 块中捕获,其中包含框架和用户应用程序的每一行代码。

我正在像对待任何其他错误一样处理"找不到控制器"或"找不到操作"之类的错误,例如"无法连接到数据库"。但我觉得后者在某种程度上更像是一个"例外",而不是一个非常常见的"未找到控制器(404)"。

此外,目前我正在使用一种错误处理,它几乎复制了 MVC 在我的框架中的工作方式,从某种意义上说,当发生错误时,我会加载一个特定的操作并为每种类型的错误加载一个特定的视图文件。我没有使用我的框架的 MVC(MVC 是指加载控制器、运行操作、加载模型和用户应用程序视图的所有机制),因为 MVC 中的错误可能会导致触发错误,这将尝试使用 MVC 管理它,这将再次触发相同的错误,然后再次加载 MVC,依此类推无限循环。

我应该如何处理框架的每个错误?现在的最佳实践是什么?

控制器恕我直言的执行可能会生成两个异常:

  • 未找到:缺少控制器或方法时
  • 权限被拒绝:当 ACL 阻止访问时

为了解决这个问题,我只会使用以下代码。您可以使用多个捕获块。

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);
}

您也可以让AccessDeniedException模型层冒泡,但通常这是一种不好的做法。异常应该在抛出它的同一抽象级别内处理,或者在发生严重异常的情况下(当对象本身无法处理它时),异常可能会穿透一个抽象边界。异常不应离开模型层,而应在中创建错误状态,并在当前 View 实例中进行处理。

关键是:与其对所有错误使用神奇的处理程序,不如在靠近错误起源的地方处理错误。

您可以在 try catch 上执行一些更合适的消息。例如:

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);
}