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

时间:2013-12-14 18:33:57

标签: php error-handling slim

我正试图围绕处理Slim框架应用程序中抛出的异常和最终页面传递的操作顺序。基本上,如果我在一个类中抛出一个Exception,我会喜欢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. 登录
  3. 停止尝试在我的数据库类中执行进一步的操作(这将全部失败并抛出致命的异常)
  4. 通过500.twig模板文件发送页面。
  5. 非常感谢任何帮助或指示。

1 个答案:

答案 0 :(得分:9)

由于您的应用程序永远不会一直到\Slim\Slim::run(),所以您已经陷入了悲伤,因为还没有配置Slim的错误处理。

要做的两件事:

1)我建议将您的数据库类(和其他类似的类)添加到Slim的Dependency Injection容器中。

$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的custom error handling

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