[英]Symfony\Component\Debug\Exception\FatalErrorException laravel Error
[英]How to debug "Symfony\Component\Debug\Exception\FatalErrorException" errors in PHP (Laravel)?
我收到客户遇到的许多错误的报告
Symfony\\Component\\Debug\\Exception\\FatalErrorException
超过 30 秒的最大执行时间
我自己无法在本地机器或生产服务器上复制它。 这个 URL 遍布整个站点,所以,我想这是一个全局性的东西,比如导致这种情况的中间件。
我正在使用Sentry.io收集数据,但异常跟踪只有 1 个条目指向Symfony
基本代码中的某个代码,最常见的是:
vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php 第 73 行
vendor/symfony/finder/Iterator/DateRangeFilterIterator.php 第 45 行
vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php 第 69 行
显然,似乎有一些与文件系统相关的东西,但由于没有跟踪,我无法看到在站点代码中在哪里查找错误。 我猜这是某种无限循环或泄漏,但没有任何痕迹可以查看,也没有一致的方法来重现问题。
我应该如何查找问题并进行调试?
有没有我可以设置的设置,或者我可以使用/启用的工具?
阅读您的聊天对话后,我看到您正在使用此.env
配置:
CACHE_DRIVER=file
SESSION_DRIVER=file
我认为这就是问题所在……我更好地解释了自己。
当您将file
驱动程序用于缓存或会话时,Laravel 将创建大量文件来存储用户会话数据或应用程序缓存数据...
如果您的电子商务正在增长并产生大量流量,那么性能可能会因为必须由框架扫描的大量文件而变慢。
我认为这可能是两种可能的解决方案:
我通常使用redis作为缓存和会话驱动程序,它速度更快,并且具有“智能缓存”的好策略,这是一个很棒的工具。
我认为如果可能的话,您也应该尝试使用它。 Memcached也可能是一个很好的解决方案。
如果您不确定异常的原因,那么您可以通过两种方式处理它
1 增加请求超时 ini_set('max_execution_time', 60); //60 秒 = 1 分钟
2 用 try catch 包装你的代码
try{
//logic goes here
}catch(\Excaption $e){
Log::error($e->getMessage().' '. $e->getFile().' '. $e->getLine());
return back()->with('error',$e->getMessage() );
}
你能注册一个关机功能吗? 即使发生超时,也会调用关闭函数。 有了它,您可以打印或保存您想要的日志文件。 我不确定是否有更好的方法在 laravel 中获取回溯,但这就是我在纯 php 中可能会做的事情(调用 debug_backtrace)。
<?php
function timedOut() {
//save to a log file instead of printing
var_dump(debug_backtrace());
}
register_shutdown_function("timedOut");
http://php.net/manual/en/function.register-shutdown-function.php
我不习惯 Laravel,但我遇到了这个问题,我通过使用 PHP 的 register_shutdown_function 解决了它。
我发现它在跟踪随机发生的错误方面非常有用。 这就是我在代码中执行此操作的方式。 你可以把它放在一个可以在每个页面上执行的公共文件中, index.php 对你来说是一个不错的选择,因为所有 Laravel 路由都通过它(我的假设)。
register_shutdown_function( "check_for_fatal" );
function check_for_fatal(){
$time = time(); //time when this error occurred
$error = error_get_last();
if (in_array($error["type"], [E_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR])){
$email_body = [];
$email_body[] = 'Date: ' . date('m-d-Y H:i:s', $time);
ob_start();
var_dump($error);
$email_body[] = ob_get_clean();
//include any other data as needed
//$body[] = "add data as appropriate";
//You can email it to yourself, but if there are lots of errors you will be bombarded with emails
mail('your_email_address@example.com', 'Subject', implode("\r\n", $email_body));
//or you can save this to some log file
}
}
看起来 PHP 正在等待一些资源,例如。 文件访问、数据库、邮件服务器(我认为是文件)。
编辑
我看到您正在使用dannyvankooten/vat.php
库,它向外部服务发出一些请求。 这可能是您问题的根源。 该库使用 curl 发出请求。 作者是设置CURLOPT_CONNECTTIMEOUT
但CURLOPT_TIMEOUT
没有设置你的脚本有时会等待更长的时间比它被限制max_execution_time
设置。
我认为你现在不应该增加超时。 如果您执行“try catch”,您可能会了解潜在的问题。 如果没有,请检查在特定方法或类中执行的操作/函数。 您可能正在查询一个巨大的表,并且可能试图使用这些信息。
如果你这样做
\DB::listen(function ($sql) {
var_dump($sql);
});
这将指示您为该操作运行了多少查询
没有办法在 try catch 中捕获它,因为它实际上是 PHP 错误而不是异常。
为了能够调试这个,你有几个选择:
我安装了 laravel-debugbar。我认为它对你有帮助。
composer require barryvdh/laravel-debugbar 接下来打开 config/app.php 并在 'providers' 数组中添加:
Barryvdh\Debugbar\ServiceProvider::class,
在别名数组类中:
'Debugbar' => Barryvdh\Debugbar\Facade::class,
你可以查看
Debugbar::measure('My long operation', function() {
// 做点什么… });
您无法捕获 php 超时错误。 当 php 解释器停止执行时会发生此错误。 您只能增加时间限制,例如 ini_set('max_execution_time', 300) 或将长时间执行的工作转换为 cron 作业,例如 laravel 任务计划。
新的哨兵版本将为您提供正确的堆栈跟踪。
您必须使用“getsentry/sentry-php”版本 >=“2.0”
老实说,您最好的方法是安装 xdebug 并以老式的方式对其进行调试,通过整个请求找到瓶颈并尝试找出它来自哪里。 Laravel 以及其他框架都旨在尽可能流畅地运行。 如果您遇到任何此类错误,则意味着您可能只是编写了错误的代码。
如果没有更多信息,也很难为您提供具体建议。 我的建议是重新创建 Laravel 应用程序所面临的环境规范(您可以使用 Docker 或 Vagrant 或任何您想到的可行的方法),然后使用 xdebug 运行以找出问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.