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

api-platform / core / 16531587208

25 Jul 2025 09:05PM UTC coverage: 0.0% (-22.1%) from 22.07%
16531587208

Pull #7225

github

web-flow
Merge 23f449a58 into 02a764950
Pull Request #7225: feat: json streamer

0 of 294 new or added lines in 31 files covered. (0.0%)

11514 existing lines in 375 files now uncovered.

0 of 51976 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/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: [
×
UNCOV
40
                'json' => ['application/problem+json', 'application/json'],
×
UNCOV
41
            ],
×
UNCOV
42
            hideHydraOperation: true,
×
UNCOV
43
            normalizationContext: [
×
UNCOV
44
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
×
UNCOV
45
                'groups' => ['jsonproblem'],
×
UNCOV
46
                'skip_null_values' => true,
×
UNCOV
47
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
×
UNCOV
48
            ],
×
UNCOV
49
        ),
×
UNCOV
50
        new Operation(
×
UNCOV
51
            errors: [],
×
UNCOV
52
            name: '_api_errors_hydra',
×
UNCOV
53
            routeName: '_api_errors',
×
UNCOV
54
            outputFormats: ['jsonld' => ['application/problem+json', 'application/ld+json']],
×
UNCOV
55
            normalizationContext: [
×
UNCOV
56
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
×
UNCOV
57
                'groups' => ['jsonld'],
×
UNCOV
58
                'skip_null_values' => true,
×
UNCOV
59
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
×
UNCOV
60
            ],
×
UNCOV
61
            links: [new Link(rel: 'http://www.w3.org/ns/json-ld#error', href: 'http://www.w3.org/ns/hydra/error')],
×
UNCOV
62
        ),
×
UNCOV
63
        new Operation(
×
UNCOV
64
            errors: [],
×
UNCOV
65
            name: '_api_errors_jsonapi',
×
UNCOV
66
            routeName: '_api_errors',
×
UNCOV
67
            hideHydraOperation: true,
×
UNCOV
68
            outputFormats: ['jsonapi' => ['application/vnd.api+json']],
×
UNCOV
69
            normalizationContext: [
×
UNCOV
70
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
×
UNCOV
71
                'disable_json_schema_serializer_groups' => false,
×
UNCOV
72
                'groups' => ['jsonapi'],
×
UNCOV
73
                'skip_null_values' => true,
×
UNCOV
74
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
×
UNCOV
75
            ],
×
UNCOV
76
        ),
×
UNCOV
77
        new Operation(
×
UNCOV
78
            errors: [],
×
UNCOV
79
            name: '_api_errors_xml',
×
UNCOV
80
            routeName: '_api_errors',
×
UNCOV
81
            outputFormats: [
×
UNCOV
82
                'xml' => ['application/xml', 'text/xml'],
×
UNCOV
83
            ],
×
UNCOV
84
            hideHydraOperation: true,
×
UNCOV
85
            normalizationContext: [
×
UNCOV
86
                SchemaFactory::OPENAPI_DEFINITION_NAME => '',
×
UNCOV
87
                'groups' => ['jsonproblem'],
×
UNCOV
88
                'skip_null_values' => true,
×
UNCOV
89
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
×
UNCOV
90
            ],
×
UNCOV
91
        ),
×
UNCOV
92
        new Operation(
×
UNCOV
93
            name: '_api_errors',
×
UNCOV
94
            hideHydraOperation: true,
×
UNCOV
95
            extraProperties: ['_api_disable_swagger_provider' => true],
×
UNCOV
96
            outputFormats: [
×
UNCOV
97
                'html' => ['text/html'],
×
UNCOV
98
                'jsonapi' => ['application/vnd.api+json'],
×
UNCOV
99
                'jsonld' => ['application/ld+json'],
×
UNCOV
100
                'json' => ['application/problem+json', 'application/json'],
×
UNCOV
101
                'xml' => ['application/xml', 'text/xml'],
×
UNCOV
102
            ],
×
UNCOV
103
        ),
×
UNCOV
104
    ],
×
UNCOV
105
    outputFormats: [
×
UNCOV
106
        'jsonapi' => ['application/vnd.api+json'],
×
UNCOV
107
        'jsonld' => ['application/ld+json'],
×
UNCOV
108
        'json' => ['application/problem+json', 'application/json'],
×
UNCOV
109
        'xml' => ['application/xml', 'text/xml'],
×
UNCOV
110
    ],
×
UNCOV
111
    provider: 'api_platform.state.error_provider',
×
UNCOV
112
    graphQlOperations: [],
×
UNCOV
113
    description: 'A representation of common errors.',
×
UNCOV
114
)]
×
115
#[ApiProperty(property: 'previous', hydra: false, readable: false)]
116
#[ApiProperty(property: 'traceAsString', hydra: false, readable: false)]
117
#[ApiProperty(property: 'string', hydra: false, readable: false)]
118
class Error extends \Exception implements ProblemExceptionInterface, HttpExceptionInterface, ErrorResourceInterface
119
{
120
    private ?string $id = null;
121

122
    public function __construct(
123
        private string $title,
124
        private string $detail,
125
        #[ApiProperty(
126
            description: 'The HTTP status code applicable to this problem.',
127
            identifier: true,
128
            writable: false,
129
            initializable: false,
130
            schema: ['type' => 'number', 'examples' => [404], 'default' => 400]
131
        )] private int $status,
132
        ?array $originalTrace = null,
133
        private ?string $instance = null,
134
        private string $type = 'about:blank',
135
        private array $headers = [],
136
        ?\Throwable $previous = null,
137
        private ?array $meta = null,
138
        private ?array $source = null,
139
    ) {
UNCOV
140
        parent::__construct($title, $status, $previous);
×
141

UNCOV
142
        if (!$originalTrace) {
×
UNCOV
143
            return;
×
144
        }
145

UNCOV
146
        $this->originalTrace = [];
×
UNCOV
147
        foreach ($originalTrace as $i => $t) {
×
UNCOV
148
            unset($t['args']); // we don't want arguments in our JSON traces, especially with xdebug
×
UNCOV
149
            $this->originalTrace[$i] = $t;
×
150
        }
151
    }
152

153
    #[Groups(['jsonapi'])]
154
    public function getId(): string
155
    {
UNCOV
156
        return $this->id ?? ((string) $this->status);
×
157
    }
158

159
    #[Groups(['jsonapi'])]
160
    #[ApiProperty(schema: ['type' => 'object'])]
161
    public function getMeta(): ?array
162
    {
UNCOV
163
        return $this->meta;
×
164
    }
165

166
    #[Groups(['jsonapi'])]
167
    #[ApiProperty(schema: [
UNCOV
168
        'type' => 'object',
×
UNCOV
169
        'properties' => [
×
UNCOV
170
            'pointer' => ['type' => 'string'],
×
UNCOV
171
            'parameter' => ['type' => 'string'],
×
UNCOV
172
            'header' => ['type' => 'string'],
×
UNCOV
173
        ],
×
UNCOV
174
    ])]
×
175
    public function getSource(): ?array
176
    {
UNCOV
177
        return $this->source;
×
178
    }
179

180
    #[SerializedName('trace')]
181
    #[Groups(['trace'])]
182
    #[ApiProperty(writable: false, initializable: false)]
183
    public ?array $originalTrace = null;
184

185
    #[Groups(['jsonld'])]
186
    #[ApiProperty(writable: false, initializable: false)]
187
    public function getDescription(): ?string
188
    {
UNCOV
189
        return $this->detail;
×
190
    }
191

192
    public static function createFromException(\Exception|\Throwable $exception, int $status): self
193
    {
UNCOV
194
        $headers = ($exception instanceof SymfonyHttpExceptionInterface || $exception instanceof HttpExceptionInterface) ? $exception->getHeaders() : [];
×
195

UNCOV
196
        return new self('An error occurred', $exception->getMessage(), $status, $exception->getTrace(), type: "/errors/$status", headers: $headers, previous: $exception->getPrevious());
×
197
    }
198

199
    #[Ignore]
200
    #[ApiProperty(readable: false)]
201
    public function getHeaders(): array
202
    {
203
        return $this->headers;
×
204
    }
205

206
    #[Ignore]
207
    public function getStatusCode(): int
208
    {
209
        return $this->status;
×
210
    }
211

212
    /**
213
     * @param array<string, string> $headers
214
     */
215
    public function setHeaders(array $headers): void
216
    {
217
        $this->headers = $headers;
×
218
    }
219

220
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
221
    #[ApiProperty(writable: false, initializable: false, description: 'A URI reference that identifies the problem type')]
222
    public function getType(): string
223
    {
UNCOV
224
        return $this->type;
×
225
    }
226

227
    public function setType(string $type): void
228
    {
229
        $this->type = $type;
×
230
    }
231

232
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
233
    #[ApiProperty(writable: false, initializable: false, description: 'A short, human-readable summary of the problem.')]
234
    public function getTitle(): ?string
235
    {
UNCOV
236
        return $this->title;
×
237
    }
238

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

244
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
245
    public function getStatus(): ?int
246
    {
UNCOV
247
        return $this->status;
×
248
    }
249

250
    public function setStatus(int $status): void
251
    {
252
        $this->status = $status;
×
253
    }
254

255
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
256
    #[ApiProperty(writable: false, initializable: false, description: 'A human-readable explanation specific to this occurrence of the problem.')]
257
    public function getDetail(): ?string
258
    {
UNCOV
259
        return $this->detail;
×
260
    }
261

262
    public function setDetail(?string $detail = null): void
263
    {
264
        $this->detail = $detail;
×
265
    }
266

267
    #[Groups(['jsonld', 'jsonproblem', 'jsonapi'])]
268
    #[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.')]
269
    public function getInstance(): ?string
270
    {
UNCOV
271
        return $this->instance;
×
272
    }
273

274
    public function setInstance(?string $instance = null): void
275
    {
276
        $this->instance = $instance;
×
277
    }
278

279
    public function setId(?string $id = null): void
280
    {
281
        $this->id = $id;
×
282
    }
283

284
    public function setMeta(?array $meta = null): void
285
    {
286
        $this->meta = $meta;
×
287
    }
288

289
    public function setSource(?array $source = null): void
290
    {
291
        $this->source = $source;
×
292
    }
293
}
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