mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Add failure handling for export generation errors
Introduce `OnExportGenerationFails` subscriber to handle export generation failures. It logs errors, updates the export status to failure, and records generation errors. Added tests to validate the new functionality.
This commit is contained in:
parent
e48bec490c
commit
d1d6a00ebf
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Export\Messenger;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\ExportGeneration;
|
||||
use Chill\MainBundle\Repository\ExportGenerationRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
|
||||
|
||||
class OnExportGenerationFails implements EventSubscriberInterface
|
||||
{
|
||||
private const LOG_PREFIX = '[export_generation failed] ';
|
||||
|
||||
public function __construct(
|
||||
private LoggerInterface $logger,
|
||||
private ExportGenerationRepository $repository,
|
||||
private EntityManagerInterface $entityManager,
|
||||
) {}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
WorkerMessageFailedEvent::class => 'onMessageFailed',
|
||||
];
|
||||
}
|
||||
|
||||
public function onMessageFailed(WorkerMessageFailedEvent $event): void
|
||||
{
|
||||
if ($event->willRetry()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $event->getEnvelope()->getMessage();
|
||||
|
||||
if (!$message instanceof ExportRequestGenerationMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $exportGeneration = $this->repository->find($message->id)) {
|
||||
throw new \UnexpectedValueException('ExportRequestGenerationMessage not found');
|
||||
}
|
||||
|
||||
$this->logger->error(self::LOG_PREFIX.'ExportRequestGenerationMessage failed to execute generation', [
|
||||
'exportId' => $message->id,
|
||||
'userId' => $message->userId,
|
||||
'alias' => $exportGeneration->getExportAlias(),
|
||||
'throwable_message' => $event->getThrowable()->getMessage(),
|
||||
'throwable_trace' => $event->getThrowable()->getTraceAsString(),
|
||||
'throwable' => get_class($event->getThrowable()),
|
||||
'full_generation_duration_failure' => microtime(true) - $exportGeneration->getCreatedAt()->getTimestamp(),
|
||||
]);
|
||||
|
||||
$this->markObjectAsFailed($event, $exportGeneration);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
private function markObjectAsFailed(WorkerMessageFailedEvent $event, ExportGeneration $exportGeneration): void
|
||||
{
|
||||
$exportGeneration->getStoredObject()->addGenerationErrors($event->getThrowable()->getMessage());
|
||||
$exportGeneration->getStoredObject()->setStatus(StoredObject::STATUS_FAILURE);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Export\Messenger;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\ExportGeneration;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\Exception\ExportGenerationException;
|
||||
use Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage;
|
||||
use Chill\MainBundle\Export\Messenger\OnExportGenerationFails;
|
||||
use Chill\MainBundle\Repository\ExportGenerationRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class OnExportGenerationFailsTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testOnExportGenerationFails(): void
|
||||
{
|
||||
$exportGeneration = new ExportGeneration('dummy');
|
||||
$exportGeneration->setCreatedAt(new \DateTimeImmutable('10 seconds ago'));
|
||||
|
||||
$repository = $this->prophesize(ExportGenerationRepository::class);
|
||||
$repository->find($exportGeneration->getId())->willReturn($exportGeneration);
|
||||
|
||||
$entityManager = $this->prophesize(EntityManagerInterface::class);
|
||||
$entityManager->flush()->shouldBeCalled();
|
||||
|
||||
$user = $this->prophesize(User::class);
|
||||
$user->getId()->willReturn(1);
|
||||
|
||||
$subscriber = new OnExportGenerationFails(new NullLogger(), $repository->reveal(), $entityManager->reveal());
|
||||
|
||||
$subscriber->onMessageFailed(new WorkerMessageFailedEvent(
|
||||
new Envelope(new ExportRequestGenerationMessage($exportGeneration, $user->reveal())),
|
||||
'dummyReceiver',
|
||||
new ExportGenerationException('dummy_exception'),
|
||||
));
|
||||
|
||||
self::assertEquals(StoredObject::STATUS_FAILURE, $exportGeneration->getStoredObject()->getStatus());
|
||||
self::assertStringContainsString('dummy_exception', $exportGeneration->getStoredObject()->getGenerationErrors());
|
||||
}
|
||||
}
|
@ -8,6 +8,8 @@ services:
|
||||
|
||||
Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessageHandler: ~
|
||||
|
||||
Chill\MainBundle\Export\Messenger\OnExportGenerationFails: ~
|
||||
|
||||
Chill\MainBundle\Export\ExportFormHelper: ~
|
||||
|
||||
Chill\MainBundle\Export\ExportGenerator: ~
|
||||
|
Loading…
x
Reference in New Issue
Block a user