Files
Inventory/src/EventSubscriber/UniqueConstraintSubscriber.php
Matthieu 826dae7712 fix(composant) : scaffold skeleton slots on creation + explicit unique constraint errors
- Add ComposantProcessor: initializes piece/product/subcomponent slots
  from ModelType skeleton requirements when a composant is created
- UniqueConstraintSubscriber: priority 256, French error messages,
  constraint name detection for specific feedback
- Migration: scaffold missing slots for existing composants in prod

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:48:23 +01:00

69 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Throwable;
final class UniqueConstraintSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => ['onKernelException', 256],
];
}
public function onKernelException(ExceptionEvent $event): void
{
$exception = $this->findUniqueConstraintViolation($event->getThrowable());
if (!$exception) {
return;
}
$constraint = $this->detectConstraintName($exception);
$error = match ($constraint) {
'unique_category_name' => 'Un élément avec ce nom existe déjà dans cette catégorie.',
default => 'Un élément avec cette valeur existe déjà.',
};
$event->setResponse(new JsonResponse(
[
'success' => false,
'error' => $error,
'constraint' => $constraint,
],
JsonResponse::HTTP_CONFLICT
));
}
private function findUniqueConstraintViolation(Throwable $throwable): ?UniqueConstraintViolationException
{
for ($current = $throwable; null !== $current; $current = $current->getPrevious()) {
if ($current instanceof UniqueConstraintViolationException) {
return $current;
}
}
return null;
}
private function detectConstraintName(UniqueConstraintViolationException $exception): ?string
{
$message = $exception->getMessage();
if (preg_match('/constraint\s+"([^"]+)"/', $message, $matches)) {
return $matches[1];
}
return null;
}
}