Refactor AuditEventDumper for enhanced error handling and customization.

- Added `AuditDumpAlreadyGeneratedException` and `AuditDumpTooMuchLines` exceptions to improve error reporting during dump operations.
- Introduced `MAX_LINES` constant to limit the number of lines in dumps.
- Modified `dump` method to accept a `StoredObject` as a parameter and handle its state transitions.
- Updated `AuditEventDumperTest` to reflect changes in `dump` method and validate error scenarios.
This commit is contained in:
2026-02-23 11:44:06 +01:00
parent 3fbdedc239
commit 7324d8dfc7
2 changed files with 34 additions and 11 deletions

View File

@@ -13,14 +13,21 @@ namespace Chill\MainBundle\Audit;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\MainBundle\Audit\Exception\AuditDumpAlreadyGeneratedException;
use Chill\MainBundle\Audit\Exception\AuditDumpTooMuchLines;
use Chill\MainBundle\Repository\AuditTrailRepository;
use Chill\MainBundle\Entity\AuditTrail;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
final readonly class AuditEventDumper
class AuditEventDumper
{
/**
* Maximum number of lines that are allowed to dump.
*/
public const MAX_LINES = 100_000;
public function __construct(
private StoredObjectManagerInterface $storedObjectManager,
private AuditTrailRepository $auditTrailRepository,
@@ -30,8 +37,29 @@ final readonly class AuditEventDumper
private UserRender $userRender,
) {}
public function dump(array $criteria, string $lang): StoredObject
/**
* @param array $criteria see the criteria from @see{AuditTrailRepository::findByCriteria}
*
* @throws \Chill\DocStoreBundle\Exception\StoredObjectManagerException
* @throws \JsonException
* @throws AuditDumpTooMuchLines
* @throws AuditDumpTooMuchLines
*/
public function dump(array $criteria, string $lang, StoredObject $storedObject): void
{
if (StoredObject::STATUS_READY === $storedObject->getStatus()) {
throw new AuditDumpAlreadyGeneratedException('Audit generation already dumped');
}
if (self::MAX_LINES < $count = $this->auditTrailRepository->countByCriteria($criteria)) {
$e = new AuditDumpTooMuchLines($count, self::MAX_LINES);
$storedObject->addGenerationErrors($e->getMessage());
$storedObject->addGenerationTrial();
$storedObject->setStatus(StoredObject::STATUS_FAILURE);
throw $e;
}
// Create a temporary file on disk (not in memory)
$tmpPath = tempnam(sys_get_temp_dir(), 'audit_export_');
if (false === $tmpPath) {
@@ -113,12 +141,8 @@ final readonly class AuditEventDumper
fclose($handle);
// Create a stored object, set auto-removal after 24h, and store content
$storedObject = new StoredObject();
$storedObject->setDeleteAt((new \DateTimeImmutable('now'))->modify('+24 hours'));
// Persist stored object so that a valid identifier exists in DB
$this->entityManager->persist($storedObject);
$storedObject->setStatus(StoredObject::STATUS_READY);
$this->entityManager->flush();
$content = file_get_contents($tmpPath) ?: '';
@@ -126,7 +150,5 @@ final readonly class AuditEventDumper
// Remove temp file from disk
@unlink($tmpPath);
return $storedObject;
}
}

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Audit;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\MainBundle\Audit\AuditEventDumper;
use Chill\MainBundle\Audit\SubjectConverterManagerInterface;
@@ -60,7 +61,7 @@ class AuditEventDumperTest extends KernelTestCase
public function testDump(): void
{
// store an audit
$storedObject = new StoredObject(status: StoredObject::STATUS_PENDING);
$user = $this->entityManager->createQuery('SELECT u FROM '.User::class.' u')
->setMaxResults(1)
->getOneOrNullResult();
@@ -92,7 +93,7 @@ class AuditEventDumperTest extends KernelTestCase
$this->userRender,
);
$storedObject = $dumper->dump($criteria, 'fr');
$dumper->dump($criteria, 'fr', $storedObject);
$read = $this->storedObjectManager->read($storedObject);