Laravel 5.1 - 致命错误

时间:2015-07-29 05:55:26

标签: laravel transactions

我有一个db事务,里面有一个事件,如下所示:

    DB::beginTransaction();

    try {
        event(new sendMessage($message, $to, $from));
    }
    catch(\Exception $e)
    {
        return 'error';
    }

    DB::commit();

此事件有2个工作侦听器设置;问题是,如果其中一个侦听器出现错误(如果出现问题),例如错误的变量名称,则事务会捕获异常'错误'永远不会返回,只记录实际错误,但错误'没有从交易中退回。

知道为什么会发生这种情况以及如何解决这个问题,以便在任何监听器因任何原因失败时抛出事务异常?

修改

因此,如果错误发生在侦听器中,则异常被正确抛出。问题似乎是事件构造函数本身有错误:

public function __construct(Message $message, $to, $from)
{
    $this->messege = $message; //notice the incorrect messege spelling
    $this->to = $to;
    $this->from = $from;
}

我原本期望从db事务中抛出异常,但是会记录下来:

[2015-07-29] local.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Call to a member function message() on null' in */Listeners/Messages/CreateMessage.php:38

其中CreateMessage.php是使用变量$ message的侦听器。

class CreateMessage {
    public function __construct()
    {
        //
    }

    public function handle(sendMessage $event)
    {
        $event->message->message()->create([  // Exception above get thrown because of the 'messege' typo in the event
            'to'      => $event->to,
            'from'    => $event->from
        ]);
    }
}

所以最后一个问题是,如果存在这样的情况,在事件监听器使用的变量名中输入错误,我该如何返回db事务错误?

1 个答案:

答案 0 :(得分:0)

确定。你无法捕捉致命错误。继续执行脚本是没有办法的。 因为它们出现后脚本不再执行。 所以你可以理解为:

此字符串后

$event->message->create(

您的代码"不存在"。 而你的catch(\Exception $e)"不存在"太。 请参阅此处{1}}

的1 16 64 4096行说明

出现致命错误后,唯一可以做出某些事情(但不想要你)的方法是使用http://php.net/manual/en/errorfunc.constants.php

laravel最后要做的就是抛弃这个例子

'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Call to a member function message() on null' in */Listeners/Messages/CreateMessage.php:38

但是你无法抓住它,之后脚本会停止。 多数民众赞成。

让我们看看我们在Laravel-core中对它的看法:

<强>供应商\ laravel \框架\ SRC \照亮\基金会\引导\ HandleExceptions.php

public function bootstrap(Application $app)
{
    $this->app = $app;

    error_reporting(-1);

    set_error_handler([$this, 'handleError']);

    set_exception_handler([$this, 'handleException']);

    register_shutdown_function([$this, 'handleShutdown']);

    if (!$app->environment('testing')) {
        ini_set('display_errors', 'Off');
    }
}

我们对register_shutdown_function([$this, 'handleShutdown']);

感兴趣
/**
 * Handle the PHP shutdown event.
 *
 * @return void
 */
public function handleShutdown()
{
    if (!is_null($error = error_get_last()) && $this->isFatal($error['type'])) {
        $this->handleException($this->fatalExceptionFromError($error, 0));
    }
}

这里我们对$this->fatalExceptionFromError($error, 0)

感兴趣
/**
 * Create a new fatal exception instance from an error array.
 *
 * @param  array  $error
 * @param  int|null  $traceOffset
 * @return \Symfony\Component\Debug\Exception\FatalErrorException
 */
protected function fatalExceptionFromError(array $error, $traceOffset = null)
{
    return new FatalErrorException(
        $error['message'], $error['type'], 0, $error['file'], $error['line'], $traceOffset
    );
}

看看这个:

* @return \Symfony\Component\Debug\Exception\FatalErrorException

他们抛出与你收到的完全相同的行为