Php 无法捕获全局异常
如果指定的日志文件有问题,Monolog将抛出一个Php 无法捕获全局异常,php,Php,如果指定的日志文件有问题,Monolog将抛出一个\UnexpectedValueException 在我的代码中,我试图捕获\UnexpectedValueException,但一直无法捕获 我的代码是: <?php namespace myNamespace; use Monolog\Logger as Monolog; use Monolog\Handler\StreamHandler; class Logger { private static $instance;
\UnexpectedValueException
在我的代码中,我试图捕获\UnexpectedValueException
,但一直无法捕获
我的代码是:
<?php
namespace myNamespace;
use Monolog\Logger as Monolog;
use Monolog\Handler\StreamHandler;
class Logger {
private static $instance;
private static function init()
{
if (!self::$instance)
{
$logger = new Monolog(MY_LOG_CHANNEL);
try
{
$logger->pushHandler(new StreamHandler(MY_LOG_PATH . "/" .
MY_LOG_NAME, Monolog::NOTICE));
}
catch (\UnexpectedValueException $e)
{
writeln("Error starting logger" . $e->getMessage());
die;
}
// and so on
据我所知,它们已经转移到了全局名称空间,所以我应该能够在那里找到它。为什么我不能?我尝试了名称空间\mynamespace\UnexpectedValueException
甚至Monolog\UnexpectedValueException
全局或本地的所有组合,但均无效
很明显我遗漏了什么,请问是什么
编辑:
在另一个类中,我正在执行一个if(file\u exists($fileName))/**do file\u get\u contents()etc*/else Logger::error($fileName.“not exists”)
当我调用self::init()
这个错误是因为我(故意)屏蔽了日志文件路径,如果它是一个有效的日志文件路径,那么代码运行正常。很明显,我想捕捉那个错误,因此需要try/catch
跟踪中的下一行是上面代码中的行:$logger->pushHandler(新的StreamHandler(MY_LOG_路径./”.MY_LOG_名称,Monolog::NOTICE))代码>
有趣的是,如果我故意拼错文件名var、file\u get\u contents
barfs和一个标准的
catch(Exception$e)
的工作原理与我对文件获取内容()的预期一样。
这是一个非常古老的问题,可能在这期间得到了解决。但是,为了将来的访问者,我想指出,在将日志条目写入给定文件时,而不是在构建时,会引发异常
按照try{}catch(){}
设置的方式,在创建StreamHandler
时会出现异常。然而,当您试图通过调用(如$logger->error(“error message”)
发送到日志时,真正的异常就会发生,因此您应该在那里捕获异常
另一方面,我认为从日志库抛出异常是最愚蠢的事情之一。日志应该是幂等的,并且不会影响正在运行的应用程序的状态。在旧的silex应用程序中,我也遇到了这个问题。我想登录到一个logstash实例,但是如果logstash不可用,它就不会中断
幸运的是,我的应用程序只使用了针对Psr\Log\LoggerInterface
键入的记录器,因此我可以编写一个decorator来防止异常在一个地方破坏应用程序,而不是在代码库中的每个调用上添加try-and-catch调用
看起来是这样的:
<?php
namespace Dreamlines\DirectBookingForm\ServiceProvider;
use Psr\Log\LoggerInterface;
/**
* DontThrowLoggerDecorator
*
* Monolog will break on info, error, etc. calls
* This decorator wrap the LoggerInterface and ensures that failure to log won't break the app
**/
class DontThrowLoggerDecorator implements LoggerInterface
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* @inheritDoc
*/
public function emergency($message, array $context = array())
{
try {
$this->logger->emergency($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function alert($message, array $context = array())
{
try {
$this->logger->alert($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function critical($message, array $context = array())
{
try {
$this->logger->critical($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function error($message, array $context = array())
{
try {
$this->logger->error($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function warning($message, array $context = array())
{
try {
$this->logger->warning($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function notice($message, array $context = array())
{
try {
$this->logger->notice($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function info($message, array $context = array())
{
try {
$this->logger->info($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function debug($message, array $context = array())
{
try {
$this->logger->debug($message, $context);
} catch (\Exception $e) {
}
}
/**
* @inheritDoc
*/
public function log($level, $message, array $context = array())
{
try {
$this->logger->log($level, $message, $context);
} catch (\Exception $e) {
}
}
}
$app['NOT_BREAKING_LOGGER'] = $app->share(
function () use ($app) {
return new DontThrowLoggerDecorator($app['monolog']);
}
);
我在我的每项服务中都注入了非破坏性日志记录程序,而不是独白日志记录程序。为什么catch中存在\before意外值异常
?错误表明无法打开日志文件,你确定这个错误不是由你的writeln
语句引发的吗?@Olivier因为它试图捕捉UnexpectedValueException
,而不是myNamespace\UnexpectedValueException
@Darren什么是完整的堆栈跟踪,它说错误是在哪一行引发的?@deceze它正在引发异常行70。
$app['NOT_BREAKING_LOGGER'] = $app->share(
function () use ($app) {
return new DontThrowLoggerDecorator($app['monolog']);
}
);