我有一个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事务错误?
答案 0 :(得分:0)
确定。你无法捕捉致命错误。继续执行脚本是没有办法的。 因为它们出现后脚本不再执行。 所以你可以理解为:
此字符串后
$event->message->create(
您的代码"不存在"。
而你的catch(\Exception $e)
"不存在"太。
请参阅此处{1}}
出现致命错误后,唯一可以做出某些事情(但不想要你)的方法是使用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
他们抛出与你收到的完全相同的行为