无法在 Laravel 中捕获异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43513989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:49:27  来源:igfitidea点击:

Can't catch exceptions in laravel

phplaraveltry-catchlaravel-5.4php-7.1

提问by SexyMF

I have the following situation:

我有以下情况:

  try {

        DB::beginTransaction();

        $task = new Task();
        $task->setTracker("");
        //thrown \Symfony\Component\Debug\Exception\FatalThrowableError


            DB::commit();

        }catch (\Exception $e){
            DB::rollBack();
            Log::error($e);
            //throw $e;
        }

I am not entering to the catch area.
Any idea why?

我没有进入捕捞区。
知道为什么吗?

update

更新

This is the error thrown:

这是抛出的错误:

[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Argument 1 passed to App\Models\Task::setTracker() must be an instance of Carbon\Carbon, integer given, called in /var/www/app/Services/ShareLogic.php on line 60

[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Argument 1 passed to App\Models\Task::setTracker() must be an instance of Carbon\Carbon, integer given, called in /var/www/app/Services/ShareLogic.php on line 60

and will not be catched

并且不会被抓住

Thanks

谢谢

回答by SexyMF

Catching Throwabledid the trick.
Have no idea why? Anyone does?

捕捉Throwable成功了。
不知道为什么?有人吗?

回答by Saeed Prez

It does not catch the exception because you are trying to catch \Exceptionwhich Symfony\Component\Debug\Exception\FatalThrowableErrordoes not extend.

因为你试图抓住它不捕获异常\ExceptionSymfony\Component\Debug\Exception\FatalThrowableError不延长。

Instead try to catch the actual exception by importing it..

而是尝试通过导入来捕获实际的异常..

use Symfony\Component\Debug\Exception\FatalThrowableError;

And then you can do..

然后你可以做..

try {
    // 
} catch(FatalThrowableError e) {
    // 
}

Edit

编辑

Ok, so in addition to the above solution it seems PHP 7+ handles error a bit differently than PHP 5. So try this..

好的,所以除了上述解决方案之外,PHP 7+ 处理错误的方式似乎与 PHP 5 略有不同。所以试试这个..

try {
    // 
} catch(Error $e) {
    // This should work
} catch(Throwable $e) {
    // This should work as well
}

回答by Cliff Edge

Symfony's Debug component is much more sophisticated in order to log and report all kinds of errors but take look at this simple example (php 7.1.x):

为了记录和报告各种错误,Symfony 的 Debug 组件要复杂得多,但请看这个简单的例子(php 7.1.x):

<?php

class MyUncatchableError extends Exception {}

function myExceptionHandler($e) {
    throw new MyUncatchableError('BANG: '.$e->getMessage());
}

set_exception_handler('myExceptionHandler');

$foo = true;

try {
    $foo->modify();
} catch (Exception $e) {
    echo 'nope';
} catch (MyUncatchableError $e) {
    echo 'nope2';
}

What will be the outcome? Well:

结果会怎样?好:

Fatal error: Uncaught MyUncatchableError: BANG: Call to a member function modify() on boolean in /in/WJErU:6

Stack trace:

  • 0 [internal function]: myExceptionHandler(Object(Error))
  • 1 {main}

    thrown in /in/WJErU on line 6

致命错误:Uncaught MyUncatchableError: BANG: Call to a member function modify() on boolean in /in/WJErU:6

堆栈跟踪:

  • 0 [内部函数]:myExceptionHandler(Object(Error))
  • 1 {主要}

    在第 6 行抛出 /in/WJErU

and you can't catch that exception because you should catch the original.. throwable here, which is Errorfor this kind of "error". You can catch it by catching "Error" class. And with PHP7 hierarchy it implements Throwable interface, that's why you can't catch it using Exception (because while Exception implements Throwable, Error is no an Exception - see: http://php.net/manual/en/language.errors.php7.php).

你不能捕获了异常,因为你应该抓住原..抛出在这里,这是错误的这样的“错误”。您可以通过捕获“错误”类来捕获它。并且使用 PHP7 层次结构它实现了 Throwable 接口,这就是为什么您不能使用 Exception 捕获它的原因(因为虽然 Exception 实现了 Throwable,但 Error 不是异常 - 请参阅:http: //php.net/manual/en/language.errors。 php7.php)。

And this is true for PHP7+ because with 5.* there was no Throwable nor Error, and doing $foo->modify();would just stop the script and return a Fatal Error. You can make your own error handler (set_error_handler) and throw an exception there (and Debug component does that for php 5.*) but this method does not work for Fatal Errors. Instead Debug component hooks into script shutdownand reads last error and throws FatalErrorException.

这对于 PHP7+ 来说是正确的,因为 5.* 没有 Throwable 和 Error,这样做$foo->modify();只会停止脚本并返回一个致命错误。您可以创建自己的错误处理程序 ( set_error_handler) 并在那里抛出异常(调试组件为 php 5.* 执行此操作)但此方法不适用于致命错误。相反,调试组件挂钩脚本关闭并读取最后一个错误并抛出 FatalErrorException

This description may not be completely accurate as I have't dug deeply into Symfony but you can get the idea here.

这个描述可能不完全准确,因为我没有深入研究 Symfony,但你可以在这里了解这个想法。