Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
ApiExceptionResponseHandler
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
1 / 1
 handle
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Api\Presentation\Exception;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Domain\Exception\ModuleNotFoundException;
12use App\Core\Engine\Domain\Exception\PermissionDeniedException;
13use App\Core\Engine\Domain\Exception\RecordNotFoundException;
14use App\Core\Engine\Domain\Exception\ValidationException;
15use App\Modules\Structure\Domain\Exception\StructureReassignRequiredException;
16use App\Shared\Infrastructure\Http\ApiResponseTrait;
17use Psr\Http\Message\ResponseFactoryInterface;
18use Psr\Http\Message\ResponseInterface;
19use Throwable;
20
21/**
22 * Maps domain and platform exceptions to RFC 9457 / RFC 7807 compliant PSR-7 JSON responses.
23 */
24final class ApiExceptionResponseHandler
25{
26    use ApiResponseTrait;
27
28    private const string SERVER_ERROR_PREFIX = 'Server error: ';
29
30    /**
31     * Translates a throwable exception into a standardized PSR-7 JSON error response.
32     *
33     * @param ResponseFactoryInterface $factory PSR-7 response factory.
34     * @param Throwable               $e       Thrown exception instance.
35     * @return ResponseInterface Formatted error response.
36     */
37    public static function handle(ResponseFactoryInterface $factory, Throwable $e): ResponseInterface
38    {
39        $instance = new self();
40
41        return match (true) {
42            $e instanceof ModuleNotFoundException,
43            $e instanceof RecordNotFoundException            => $instance->jsonError(
44                $factory,
45                $e->getMessage(),
46                404
47            ),
48            $e instanceof PermissionDeniedException          => $instance->jsonError(
49                $factory,
50                $e->getMessage(),
51                403
52            ),
53            $e instanceof StructureReassignRequiredException => $instance->jsonError(
54                $factory,
55                $e->getMessage(),
56                422
57            ),
58            $e instanceof ValidationException                => $instance->jsonValidation(
59                $factory,
60                $e->getErrors()
61            ),
62            default                                          => $instance->jsonError(
63                $factory,
64                self::SERVER_ERROR_PREFIX . $e->getMessage(),
65                500
66            ),
67        };
68    }
69}