当在路由之外抛出异常时,如何在Slim框架中传递错误页面


How can I deliver an error page in Slim framework when an Exception is thrown outside of a route?

我正试图了解处理Slim框架应用程序中抛出的异常和最终页面交付的操作顺序。基本上,如果我在类中抛出异常,我希望Slim提供我漂亮的Twig 500页面,但当异常抛出到路由之外时,我甚至无法让Slim提供自己的正常错误页面。

给定这个数据库类构造函数:

public function __construct(array $connection, 'Slim'Slim $slim) {
  $this->slim = $slim;
  try {
    $this->db = new 'PDO(...);
    $this->db->setAttribute('PDO::ATTR_EMULATE_PREPARES, FALSE);
    $this->db->setAttribute('PDO::ATTR_ERRMODE, 'PDO::ERRMODE_EXCEPTION);
 } catch ('PDOException $e) {
    // How can I kill further execution here and have Slim deliver a 500?
 }
}

如果我运行$this->slim->error();,我得到Fatal error: Uncaught exception 'Slim'Exception'Stop'

理想情况下,我想做一些类似的事情:

  1. 通过$this-slim->log->error("Unable to connect to database.");记录
  2. 停止尝试在我的DB类中执行进一步的操作(这些操作都会失败并引发致命异常)
  3. 通过500.twig模板文件传递页面

如有任何帮助或指示,我们将不胜感激。

您正陷入悲伤之中,因为Slim的错误处理尚未配置,因为您的应用程序从未完全进入'Slim'Slim::run()

两件事要做:

1) 我建议将您的数据库类(以及其他类似类)添加到Slim的依赖注入容器中。

$app->container->singleton('db', function () use ($app) {
    return new Database($app);
});

这将允许延迟加载数据库连接。在你使用它之前,类不会被创建。在这一点上,我假设你在一个路由中,'Slim'Slim::run()将被调用,Slim错误处理将到位。

2) 既然在你的应用程序完全配置之前不会发生异常,你可以使用日志记录:

public function __construct('Slim'Slim $app) {
    $this->slim = $app;
    try {
        $this->db = new 'PDO('sqlite:/does/not/exist');
    } catch ('PDOException $p) {
        $this->slim->log->error('BAD THINGS');
        return $this->slim->error();
    }
    return $this;
}

以及Slim的自定义错误处理。

$app->error(function('Exception $e) use ($app) {
    if ($e instanceof 'PDOException) {
        return $app->render('500.twig', array(), 500);
    }
});