异常Eventlistener没有捕获RabbitMQ使用者的异常
I'm creating a Microservice in Symfony where I need to use RabbitMQ to consume messages to create a document. The consumer is working but whenever a Exception is thrown I want to log the Exception in a format and in a separate log file.
I'm using Symfony 4.2 and all Exceptions that are thrown are logged in the dev.log. I made a new channel in Monolog and called in exception, so that I can manage my loggings.
For this manner I am using an ExceptionListener and I followed the instructions from the Symfony Docs.
I have my Consumer setup as follows
public function execute(AMQPMessage $msg): int
{
try {
return $this->documentService->createDocument($this->serializer->deserialize($msg->body, 'array', 'json'));
} catch (\Exception $e) {
$this->logger->error($e);
return ConsumerInterface::MSG_REJECT;
}
}
And inside the service I have the following:
try {
...
$template = $this->templateRepository->findOneByName($messageData['template']);
if ($template === null) throw new \Exception('Template does not exist');
...
return ConsumerInterface::MSG_ACK;
} catch (\Exception $e) {
$this->logger->error($e);
return ConsumerInterface::MSG_REJECT;
}
Im logging on both classes but when an Exceptions throws I get the Exception in the console but the Listener does not catches the ExceptionEvent.
I have tried different events and I added http-kernel package to the Symfony, since I am using Symfony Flex I don't have all packages.
I have registered my Listener in services.yaml as following:
App\EventListener\DocumentExceptionListener:
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
arguments:
$logger: '@monolog.logger.exception' # Log all exceptions to a separate log file
And my ExceptionListener is as following:
public function __construct(LoggerInterface $logger, SerializerInterface $serializer)
{
$this->logger = $logger;
$this->serializer = $serializer;
$this->logger->info('Starting to listen...');
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$this->logger->info('currently listening...');
$this->log($event->getException());
}
private function log(\Exception $exception)
{
$log = [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'called' => [
'file' => $exception->getTrace()[0]['file'],
'line' => $exception->getTrace()[0]['line'],
],
'occurred' => [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
],
];
if ($exception->getPrevious() instanceof Exception) {
$log += [
'previous' => [
'message' => $exception->getPrevious()->getMessage(),
'exception' => get_class($exception->getPrevious()),
'file' => $exception->getPrevious()->getFile(),
'line' => $exception->getPrevious()->getLine(),
],
];
}
$this->logger->error($this->serializer->serialize($log, 'json'));
}
My output right now is:
exception.INFO: Starting to listen... [] []
I read the word "console" in your question. If it is a console exception (because it is about a command execution) you have to tag your listener another way:
tags:
- { name: kernel.event_listener, event: console.error }
See the console.error
event name here.
See more here: Events and Event Listeners