|
16 | 16 | use ApiPlatform\Api\IdentifiersExtractorInterface;
|
17 | 17 | use ApiPlatform\ApiResource\Error;
|
18 | 18 | use ApiPlatform\Metadata\Error as ErrorOperation;
|
| 19 | +use ApiPlatform\Metadata\Exception\ProblemExceptionInterface; |
19 | 20 | use ApiPlatform\Metadata\HttpOperation;
|
20 | 21 | use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
|
21 | 22 | use ApiPlatform\Metadata\ResourceClassResolverInterface;
|
@@ -64,32 +65,44 @@ protected function duplicateRequest(\Throwable $exception, Request $request): Re
|
64 | 65 | $apiOperation = $this->initializeOperation($request);
|
65 | 66 | $format = $this->getRequestFormat($request, $this->errorFormats, false);
|
66 | 67 |
|
67 |
| - if ($this->resourceClassResolver?->isResourceClass($exception::class)) { |
68 |
| - $resourceCollection = $this->resourceMetadataCollectionFactory->create($exception::class); |
69 |
| - |
70 |
| - $operation = null; |
71 |
| - foreach ($resourceCollection as $resource) { |
72 |
| - foreach ($resource->getOperations() as $op) { |
73 |
| - foreach ($op->getOutputFormats() as $key => $value) { |
74 |
| - if ($key === $format) { |
75 |
| - $operation = $op; |
76 |
| - break 3; |
| 68 | + if ($this->resourceMetadataCollectionFactory) { |
| 69 | + if ($this->resourceClassResolver?->isResourceClass($exception::class)) { |
| 70 | + $resourceCollection = $this->resourceMetadataCollectionFactory->create($exception::class); |
| 71 | + |
| 72 | + $operation = null; |
| 73 | + foreach ($resourceCollection as $resource) { |
| 74 | + foreach ($resource->getOperations() as $op) { |
| 75 | + foreach ($op->getOutputFormats() as $key => $value) { |
| 76 | + if ($key === $format) { |
| 77 | + $operation = $op; |
| 78 | + break 3; |
| 79 | + } |
77 | 80 | }
|
78 | 81 | }
|
79 | 82 | }
|
80 |
| - } |
81 | 83 |
|
82 |
| - // No operation found for the requested format, we take the first available |
83 |
| - if (!$operation) { |
84 |
| - $operation = $resourceCollection->getOperation(); |
| 84 | + // No operation found for the requested format, we take the first available |
| 85 | + if (!$operation) { |
| 86 | + $operation = $resourceCollection->getOperation(); |
| 87 | + } |
| 88 | + $errorResource = $exception; |
| 89 | + if ($errorResource instanceof ProblemExceptionInterface && $operation instanceof HttpOperation) { |
| 90 | + $statusCode = $this->getStatusCode($apiOperation, $request, $operation, $exception); |
| 91 | + $operation = $operation->withStatus($statusCode); |
| 92 | + $errorResource->setStatus($statusCode); |
| 93 | + } |
| 94 | + } else { |
| 95 | + // Create a generic, rfc7807 compatible error according to the wanted format |
| 96 | + $operation = $this->resourceMetadataCollectionFactory->create(Error::class)->getOperation($this->getFormatOperation($format)); |
| 97 | + // status code may be overriden by the exceptionToStatus option |
| 98 | + $statusCode = 500; |
| 99 | + if ($operation instanceof HttpOperation) { |
| 100 | + $statusCode = $this->getStatusCode($apiOperation, $request, $operation, $exception); |
| 101 | + $operation = $operation->withStatus($statusCode); |
| 102 | + } |
| 103 | + |
| 104 | + $errorResource = Error::createFromException($exception, $statusCode); |
85 | 105 | }
|
86 |
| - $errorResource = $exception; |
87 |
| - } elseif ($this->resourceMetadataCollectionFactory) { |
88 |
| - // Create a generic, rfc7807 compatible error according to the wanted format |
89 |
| - /** @var HttpOperation $operation */ |
90 |
| - $operation = $this->resourceMetadataCollectionFactory->create(Error::class)->getOperation($this->getFormatOperation($format)); |
91 |
| - $operation = $operation->withStatus($this->getStatusCode($apiOperation, $request, $operation, $exception)); |
92 |
| - $errorResource = Error::createFromException($exception, $operation->getStatus()); |
93 | 106 | } else {
|
94 | 107 | /** @var HttpOperation $operation */
|
95 | 108 | $operation = new ErrorOperation(name: '_api_errors_problem', class: Error::class, outputFormats: ['jsonld' => ['application/ld+json']], normalizationContext: ['groups' => ['jsonld'], 'skip_null_values' => true]);
|
|
0 commit comments