• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

0 of 2 new or added lines in 1 file covered. (0.0%)

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.07
/src/State/ApiResource/Error.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\State\ApiResource;
15

16
use ApiPlatform\JsonSchema\SchemaFactory;
17
use ApiPlatform\Metadata\ApiProperty;
18
use ApiPlatform\Metadata\Error as Operation;
19
use ApiPlatform\Metadata\ErrorResource;
20
use ApiPlatform\Metadata\ErrorResourceInterface;
21
use ApiPlatform\Metadata\Exception\HttpExceptionInterface;
22
use ApiPlatform\Metadata\Exception\ProblemExceptionInterface;
23
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface as SymfonyHttpExceptionInterface;
24
use Symfony\Component\Serializer\Annotation\Groups;
25
use Symfony\Component\Serializer\Annotation\Ignore;
26
use Symfony\Component\Serializer\Annotation\SerializedName;
27
use Symfony\Component\WebLink\Link;
28

29
#[ErrorResource(
UNCOV
30
    uriVariables: ['status'],
UNCOV
31
    requirements: ['status' => '\d+'],
UNCOV
32
    uriTemplate: '/errors/{status}{._format}',
UNCOV
33
    openapi: false,
UNCOV
34
    operations: [
UNCOV
35
        new Operation(
UNCOV
36
            errors: [],
UNCOV
37
            name: '_api_errors_problem',
UNCOV
38
            routeName: '_api_errors',
UNCOV
39
            outputFormats: ['json' => ['application/problem+json', 'application/json']],
UNCOV
40
            hideHydraOperation: true,
UNCOV
41
            normalizationContext: [
UNCOV
42
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
UNCOV
43
                'groups' => ['jsonproblem'],
UNCOV
44
                'skip_null_values' => true,
UNCOV
45
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
46
            ],
UNCOV
47
        ),
UNCOV
48
        new Operation(
UNCOV
49
            errors: [],
UNCOV
50
            name: '_api_errors_hydra',
UNCOV
51
            routeName: '_api_errors',
UNCOV
52
            outputFormats: ['jsonld' => ['application/problem+json', 'application/ld+json']],
UNCOV
53
            normalizationContext: [
UNCOV
54
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
UNCOV
55
                'groups' => ['jsonld'],
UNCOV
56
                'skip_null_values' => true,
UNCOV
57
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
58
            ],
UNCOV
59
            links: [new Link(rel: 'http://www.w3.org/ns/json-ld#error', href: 'http://www.w3.org/ns/hydra/error')],
UNCOV
60
        ),
UNCOV
61
        new Operation(
UNCOV
62
            errors: [],
UNCOV
63
            name: '_api_errors_jsonapi',
UNCOV
64
            routeName: '_api_errors',
UNCOV
65
            hideHydraOperation: true,
UNCOV
66
            outputFormats: ['jsonapi' => ['application/vnd.api+json']],
UNCOV
67
            normalizationContext: [
UNCOV
68
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
UNCOV
69
                'disable_json_schema_serializer_groups' => false,
UNCOV
70
                'groups' => ['jsonapi'],
UNCOV
71
                'skip_null_values' => true,
UNCOV
72
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
73
            ],
UNCOV
74
        ),
UNCOV
75
        new Operation(
UNCOV
76
            name: '_api_errors',
UNCOV
77
            hideHydraOperation: true,
UNCOV
78
            extraProperties: ['_api_disable_swagger_provider' => true],
UNCOV
79
            outputFormats: [
UNCOV
80
                'html' => ['text/html'],
UNCOV
81
                'jsonapi' => ['application/vnd.api+json'],
UNCOV
82
                'jsonld' => ['application/ld+json'],
UNCOV
83
                'json' => ['application/problem+json', 'application/json'],
UNCOV
84
            ],
UNCOV
85
        ),
UNCOV
86
    ],
UNCOV
87
    outputFormats: ['jsonapi' => ['application/vnd.api+json'], 'jsonld' => ['application/ld+json'], 'json' => ['application/problem+json', 'application/json']],
UNCOV
88
    provider: 'api_platform.state.error_provider',
UNCOV
89
    graphQlOperations: [],
UNCOV
90
    description: 'A representation of common errors.',
UNCOV
91
)]
92
#[ApiProperty(property: 'previous', hydra: false, readable: false)]
93
#[ApiProperty(property: 'traceAsString', hydra: false, readable: false)]
94
#[ApiProperty(property: 'string', hydra: false, readable: false)]
95
class Error extends \Exception implements ProblemExceptionInterface, HttpExceptionInterface, ErrorResourceInterface
96
{
97
    private ?string $id = null;
98

99
    public function __construct(
100
        private string $title,
101
        private string $detail,
102
        #[ApiProperty(
103
            description: 'The HTTP status code applicable to this problem.',
104
            identifier: true,
105
            writable: false,
106
            initializable: false,
107
            schema: ['type' => 'number', 'examples' => [404], 'default' => 400]
108
        )] private int $status,
109
        ?array $originalTrace = null,
110
        private ?string $instance = null,
111
        private string $type = 'about:blank',
112
        private array $headers = [],
113
        ?\Throwable $previous = null,
114
        private ?array $meta = null,
115
        private ?array $source = null,
116
    ) {
UNCOV
117
        parent::__construct($title, $status, $previous);
68✔
118

UNCOV
119
        if (!$originalTrace) {
68✔
UNCOV
120
            return;
3✔
121
        }
122

UNCOV
123
        $this->originalTrace = [];
65✔
UNCOV
124
        foreach ($originalTrace as $i => $t) {
65✔
UNCOV
125
            unset($t['args']); // we don't want arguments in our JSON traces, especially with xdebug
65✔
UNCOV
126
            $this->originalTrace[$i] = $t;
65✔
127
        }
128
    }
129

130
    #[Groups(['jsonapi'])]
131
    public function getId(): string
132
    {
UNCOV
133
        return $this->id ?? ((string) $this->status);
3✔
134
    }
135

136
    #[Groups(['jsonapi'])]
137
    #[ApiProperty(schema: ['type' => 'object'])]
138
    public function getMeta(): ?array
139
    {
UNCOV
140
        return $this->meta;
3✔
141
    }
142

143
    #[Groups(['jsonapi'])]
144
    #[ApiProperty(schema: [
UNCOV
145
        'type' => 'object',
UNCOV
146
        'properties' => [
UNCOV
147
            'pointer' => ['type' => 'string'],
UNCOV
148
            'parameter' => ['type' => 'string'],
UNCOV
149
            'header' => ['type' => 'string'],
UNCOV
150
        ],
UNCOV
151
    ])]
152
    public function getSource(): ?array
153
    {
UNCOV
154
        return $this->source;
3✔
155
    }
156

157
    #[SerializedName('trace')]
158
    #[Groups(['trace'])]
159
    #[ApiProperty(writable: false, initializable: false)]
160
    public ?array $originalTrace = null;
161

162
    #[Groups(['jsonld'])]
163
    #[ApiProperty(writable: false, initializable: false)]
164
    public function getDescription(): ?string
165
    {
UNCOV
166
        return $this->detail;
53✔
167
    }
168

169
    public static function createFromException(\Exception|\Throwable $exception, int $status): self
170
    {
UNCOV
171
        $headers = ($exception instanceof SymfonyHttpExceptionInterface || $exception instanceof HttpExceptionInterface) ? $exception->getHeaders() : [];
65✔
172

UNCOV
173
        return new self('An error occurred', $exception->getMessage(), $status, $exception->getTrace(), type: "/errors/$status", headers: $headers, previous: $exception->getPrevious());
65✔
174
    }
175

176
    #[Ignore]
177
    #[ApiProperty(readable: false)]
178
    public function getHeaders(): array
179
    {
180
        return $this->headers;
×
181
    }
182

183
    #[Ignore]
184
    public function getStatusCode(): int
185
    {
186
        return $this->status;
×
187
    }
188

189
    /**
190
     * @param array<string, string> $headers
191
     */
192
    public function setHeaders(array $headers): void
193
    {
194
        $this->headers = $headers;
×
195
    }
196

197
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
198
    #[ApiProperty(writable: false, initializable: false, description: 'A URI reference that identifies the problem type')]
199
    public function getType(): string
200
    {
UNCOV
201
        return $this->type;
68✔
202
    }
203

204
    public function setType(string $type): void
205
    {
206
        $this->type = $type;
×
207
    }
208

209
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
210
    #[ApiProperty(writable: false, initializable: false, description: 'A short, human-readable summary of the problem.')]
211
    public function getTitle(): ?string
212
    {
UNCOV
213
        return $this->title;
68✔
214
    }
215

216
    public function setTitle(?string $title = null): void
217
    {
218
        $this->title = $title;
×
219
    }
220

221
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
222
    public function getStatus(): ?int
223
    {
UNCOV
224
        return $this->status;
68✔
225
    }
226

227
    public function setStatus(int $status): void
228
    {
229
        $this->status = $status;
×
230
    }
231

232
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
233
    #[ApiProperty(writable: false, initializable: false, description: 'A human-readable explanation specific to this occurrence of the problem.')]
234
    public function getDetail(): ?string
235
    {
UNCOV
236
        return $this->detail;
68✔
237
    }
238

239
    public function setDetail(?string $detail = null): void
240
    {
241
        $this->detail = $detail;
×
242
    }
243

244
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
245
    #[ApiProperty(writable: false, initializable: false, description: 'A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.')]
246
    public function getInstance(): ?string
247
    {
UNCOV
248
        return $this->instance;
68✔
249
    }
250

251
    public function setInstance(?string $instance = null): void
252
    {
253
        $this->instance = $instance;
×
254
    }
255

256
    public function setId(?string $id = null): void
257
    {
258
        $this->id = $id;
×
259
    }
260

261
    public function setMeta(?array $meta = null): void
262
    {
263
        $this->meta = $meta;
×
264
    }
265

266
    public function setSource(?array $source = null): void
267
    {
268
        $this->source = $source;
×
269
    }
270
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc