【问题标题】:Error even when using a Try/Catch block in PHP即使在 PHP 中使用 Try/Catch 块也会出错
【发布时间】:2015-05-12 17:15:04
【问题描述】:

我有一个 Laravel/PHP 应用程序,代码如下:

try {
        //gets the day of the last record for logged in user
        $lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date;
        //convert to date
        $lastTime = \Carbon\Carbon::createFromFormat('Y-m-d', $lastRecord);
    }
    catch(Exception $e) {
        $lastTime = \Carbon\Carbon::now($user->timezone)->addDays(-1);
    }

但我仍然收到错误:

ErrorException in Habit.php line 104:
Trying to get property of non-object

现在我很困惑.. 主要想法是有时会失败,然后继续到 catch 块。怎么还是报错?

【问题讨论】:

  • 您确定没有在您的 catch 块中引起另一个异常吗?你确定now() 无条件返回一个对象?其中#104 是哪一行?
  • 第 104 行是:$lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date;
  • 是否有可能 Laravel 有一些调试设置,即使在 try/catch 块上也会引发每个错误?
  • 好吧,追查调用树。 var_dump($user); var_dump($user->records()) 等等...看看哪些调用返回的不是对象。
  • 你能发布你得到的异常调用堆栈吗?

标签: php laravel


【解决方案1】:

只是一个猜测,但试试这个

try {
    //gets the day of the last record for logged in user
    $lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date;
    //convert to date
    $lastTime = \Carbon\Carbon::createFromFormat('Y-m-d', $lastRecord);
}
catch(\Exception $e) {
    $lastTime = \Carbon\Carbon::now($user->timezone)->addDays(-1);
}

即在Exception前面添加一个前导命名空间分隔符。我的猜测是您在命名空间文件中使用此代码。当你做这样的事情时

namespace App\Some\Somenamespace;
...
catch(Exception $e) {
...

PHP 假定您要捕获名称为 App\Some\Somenamespace\Exception 的异常。由于这不是抛出的异常,并且全局 PHP \Exception 没有第二个 catch,因此 PHP 抱怨未捕获的异常。您需要明确地将异常称为全局

catch(\Exception $e) {

或将其导入当前命名空间

namespace App\Some\Somenamespace\;
use Exception;
...
catch(Exception $e) {
...

FWIW,我仍然一直这样做。旧习难改。

【讨论】:

  • 就是这样..我很困惑,因为错误在另一行..但现在它起作用了..谢谢艾伦!
【解决方案2】:

异常表示您正在访问非对象的属性。这意味着 $user 本身或链中的属性之一不存在。可以通过检查返回值来避免这种情况。

但如果你仍然想捕获致命错误,你可以安装一个全局关闭处理程序,如下所示:

register_shutdown_function( "shutdown_handler" );

function fatal_handler() {
    $errfile = "unknown file";
    $errstr  = "shutdown";
    $errno   = E_CORE_ERROR;
    $errline = 0;

    $error = error_get_last();

    if( $error !== NULL) {
        $errno   = $error["type"];
        $errfile = $error["file"];
        $errline = $error["line"];
        $errstr  = $error["message"];

        error_mail(format_error( $errno, $errstr, $errfile, $errline));
    }
}

取自this SO postthis SO post

【讨论】:

  • 一个ErrorException 具有全局PHP \Exception 作为祖先,catch (\Exception $e)(或非命名空间文件中的catch (Exception $e))将始终捕获异常。
猜你喜欢
  • 2014-08-28
  • 2017-01-30
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 2018-02-14
  • 1970-01-01
相关资源
最近更新 更多