feat(arcadia): add dedicated NotFound exceptions for Employee, IncoSheet and IncoComposition

This commit is contained in:
Jérémy Munsch 2026-08-18 12:09:35 +02:00
parent 90eff3cc99
commit e7f5f71005
Signed by: forge-joniko
GPG key ID: D7EFE2F5CB6CC0E4
14 changed files with 179 additions and 14 deletions

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Application\Arcadia\Exceptions;
use Domain\Models\ValueObjects\Employees\ArcadiaEmployeeId;
use Shared\DDD\Exception\NotFoundException;
final class EmployeeNotFoundException extends NotFoundException
{
public static function forEmployee(ArcadiaEmployeeId | string $id): self
{
return new self("Employee '{$id}' not found.");
}
}

View file

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Application\Arcadia\Exceptions;
use Domain\Models\ValueObjects\Inco\IncoId;
use Shared\DDD\Exception\NotFoundException;
final class IncoCompositionNotFoundException extends NotFoundException
{
public static function forInco(IncoId | string $incoId): self
{
return new self("IncoComposition for inco '{$incoId}' not found.");
}
public static function forEntity(string $entity, string $id): self
{
return new self("{$entity} '{$id}' not found.");
}
}

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Application\Arcadia\Exceptions;
use Domain\Models\ValueObjects\Inco\IncoId;
use Shared\DDD\Exception\NotFoundException;
final class IncoSheetNotFoundException extends NotFoundException
{
public static function forIncoSheet(IncoId | string $id): self
{
return new self("IncoSheet '{$id}' not found.");
}
}

View file

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Application\Arcadia\Usecase\Employees\Find;
use Application\Shared\Exceptions\NotFoundException;
use Application\Arcadia\Exceptions\EmployeeNotFoundException;
use Domain\Ports\Directories\EmployeeDirectory;
use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
@ -26,7 +26,7 @@ final readonly class FindEmployee implements Usecase
$employee = $this->directory->find($input->id);
if ($employee === null) {
throw NotFoundException::forEntity('Employee', (string) $input->id);
throw EmployeeNotFoundException::forEmployee($input->id);
}
return new Output(

View file

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Application\Arcadia\Usecase\IncoCompositions\Find;
use Application\Shared\Exceptions\NotFoundException;
use Application\Arcadia\Exceptions\IncoCompositionNotFoundException;
use Domain\Ports\Directories\IncoCompositionDirectory;
use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
@ -26,7 +26,7 @@ final readonly class FindIncoComposition implements Usecase
$incoComposition = $this->directory->findByIncoId($input->incoId);
if ($incoComposition === null) {
throw NotFoundException::forEntity('IncoComposition', (string) $input->incoId->value);
throw IncoCompositionNotFoundException::forInco($input->incoId);
}
return new Output(

View file

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Application\Arcadia\Usecase\IncoSheets\Find;
use Application\Shared\Exceptions\NotFoundException;
use Application\Arcadia\Exceptions\IncoSheetNotFoundException;
use Domain\Ports\Directories\IncoSheetDirectory;
use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
@ -26,7 +26,7 @@ final readonly class FindIncoSheet implements Usecase
$incoSheet = $this->directory->find($input->id);
if ($incoSheet === null) {
throw NotFoundException::forEntity('IncoSheet', $input->id->value);
throw IncoSheetNotFoundException::forIncoSheet($input->id);
}
return new Output(

View file

@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Presentation\Api\V1\Exceptions;
use Application\Shared\Exceptions\NotFoundException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Validation\ValidationException;
use Shared\DDD\Exception\NotFoundException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable;

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Presentation\Web\Exceptions;
use Application\Shared\Exceptions\NotFoundException;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Shared\DDD\Exception\NotFoundException;
use Throwable;
final readonly class WebExceptionRenderer

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Exceptions;
use Application\Arcadia\Exceptions\EmployeeNotFoundException;
use Domain\Models\ValueObjects\Employees\ArcadiaEmployeeId;
use Shared\DDD\Exception\NotFoundException;
covers(EmployeeNotFoundException::class);
describe('EmployeeNotFoundException Unit Tests', function (): void {
it('creates exception from value object', function (): void {
// GIVEN
$id = new ArcadiaEmployeeId('01155902');
// WHEN
$exception = EmployeeNotFoundException::forEmployee($id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("Employee '01155902' not found.");
});
it('creates exception from string', function (): void {
// GIVEN
$id = '01155902';
// WHEN
$exception = EmployeeNotFoundException::forEmployee($id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("Employee '01155902' not found.");
});
});

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Exceptions;
use Application\Arcadia\Exceptions\IncoCompositionNotFoundException;
use Domain\Models\ValueObjects\Inco\IncoId;
use Shared\DDD\Exception\NotFoundException;
covers(IncoCompositionNotFoundException::class);
describe('IncoCompositionNotFoundException Unit Tests', function (): void {
it('creates exception for inco id value object', function (): void {
// GIVEN
$id = new IncoId('12345');
// WHEN
$exception = IncoCompositionNotFoundException::forInco($id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("IncoComposition for inco '12345' not found.");
});
it('creates exception for generic entity', function (): void {
// GIVEN
$entity = 'IncoComposition';
$id = '12345';
// WHEN
$exception = IncoCompositionNotFoundException::forEntity($entity, $id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("IncoComposition '12345' not found.");
});
});

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Exceptions;
use Application\Arcadia\Exceptions\IncoSheetNotFoundException;
use Domain\Models\ValueObjects\Inco\IncoId;
use Shared\DDD\Exception\NotFoundException;
covers(IncoSheetNotFoundException::class);
describe('IncoSheetNotFoundException Unit Tests', function (): void {
it('creates exception from value object', function (): void {
// GIVEN
$id = new IncoId('12345');
// WHEN
$exception = IncoSheetNotFoundException::forIncoSheet($id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("IncoSheet '12345' not found.");
});
it('creates exception from string', function (): void {
// GIVEN
$id = '12345';
// WHEN
$exception = IncoSheetNotFoundException::forIncoSheet($id);
// THEN
expect($exception)->toBeInstanceOf(NotFoundException::class)
->and($exception->getMessage())->toBe("IncoSheet '12345' not found.");
});
});

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Usecase\Employees;
use Application\Arcadia\Exceptions\EmployeeNotFoundException;
use Application\Arcadia\Usecase\Employees\Find\FindEmployee;
use Application\Arcadia\Usecase\Employees\Find\Input;
use Application\Arcadia\Usecase\Employees\Find\Output;
use Application\Shared\Exceptions\NotFoundException;
use Domain\Models\Entities\Employee;
use Domain\Models\ValueObjects\Employees\ArcadiaEmployeeId;
use Domain\Models\ValueObjects\EstablishmentCode;
@ -72,6 +72,6 @@ describe('FindEmployee Usecase Unit Tests', function (): void {
$execution = fn () => $usecase->execute($input);
// THEN
expect($execution)->toThrow(NotFoundException::class, "Employee '01155902' not found.");
expect($execution)->toThrow(EmployeeNotFoundException::class, "Employee '01155902' not found.");
});
});

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Usecase\IncoCompositions;
use Application\Arcadia\Exceptions\IncoCompositionNotFoundException;
use Application\Arcadia\Usecase\IncoCompositions\Find\FindIncoComposition;
use Application\Arcadia\Usecase\IncoCompositions\Find\Input;
use Application\Arcadia\Usecase\IncoCompositions\Find\Output;
use Application\Shared\Exceptions\NotFoundException;
use Domain\Models\Entities\Inco\Composition\IncoComposition;
use Domain\Models\ValueObjects\Inco\Composition\AminoAcids;
use Domain\Models\ValueObjects\Inco\Composition\CarbohydratesDetail;
@ -117,6 +117,6 @@ describe('FindIncoComposition Usecase Unit Tests', function (): void {
$input = new Input($incoId);
// WHEN & THEN
expect(fn () => $usecase->execute($input))->toThrow(NotFoundException::class);
expect(fn () => $usecase->execute($input))->toThrow(IncoCompositionNotFoundException::class);
});
});

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Tests\Unit\Application\Arcadia\Usecase\IncoSheets;
use Application\Arcadia\Exceptions\IncoSheetNotFoundException;
use Application\Arcadia\Usecase\IncoSheets\Find\FindIncoSheet;
use Application\Arcadia\Usecase\IncoSheets\Find\Input;
use Application\Arcadia\Usecase\IncoSheets\Find\Output;
use Application\Shared\Exceptions\NotFoundException;
use Domain\Models\Entities\Inco\IncoSheet;
use Domain\Models\ValueObjects\Inco\Allegations;
use Domain\Models\ValueObjects\Inco\Brand;
@ -79,6 +79,6 @@ describe('FindIncoSheet Usecase Unit Tests', function (): void {
// WHEN & THEN
expect(fn () => $usecase->execute($input))
->toThrow(NotFoundException::class, "IncoSheet '99999' not found.");
->toThrow(IncoSheetNotFoundException::class, "IncoSheet '99999' not found.");
});
});