• 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

91.18
/src/Validator/Exception/ValidationException.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\Validator\Exception;
15

16
use ApiPlatform\Metadata\ApiProperty;
17
use ApiPlatform\Metadata\Error as ErrorOperation;
18
use ApiPlatform\Metadata\ErrorResource;
19
use ApiPlatform\Metadata\Exception\HttpExceptionInterface;
20
use ApiPlatform\Metadata\Exception\ProblemExceptionInterface;
21
use ApiPlatform\Metadata\Exception\RuntimeException;
22
use ApiPlatform\Metadata\Util\CompositeIdentifierParser;
23
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface as SymfonyHttpExceptionInterface;
24
use Symfony\Component\Serializer\Annotation\Groups;
25
use Symfony\Component\Serializer\Annotation\SerializedName;
26
use Symfony\Component\Validator\ConstraintViolationList;
27
use Symfony\Component\Validator\ConstraintViolationListInterface;
28
use Symfony\Component\WebLink\Link;
29

30
/**
31
 * Thrown when a validation error occurs.
32
 *
33
 * @author Kévin Dunglas <dunglas@gmail.com>
34
 */
35
#[ErrorResource(
UNCOV
36
    uriTemplate: '/validation_errors/{id}',
UNCOV
37
    status: 422,
UNCOV
38
    uriVariables: ['id'],
UNCOV
39
    openapi: false,
UNCOV
40
    outputFormats: ['jsonapi' => ['application/vnd.api+json'], 'jsonld' => ['application/ld+json'], 'json' => ['application/problem+json', 'application/json']],
UNCOV
41
    provider: 'api_platform.validator.state.error_provider',
UNCOV
42
    shortName: 'ConstraintViolation',
UNCOV
43
    description: 'Unprocessable entity',
UNCOV
44
    operations: [
UNCOV
45
        new ErrorOperation(
UNCOV
46
            name: '_api_validation_errors_problem',
UNCOV
47
            outputFormats: ['json' => ['application/problem+json']],
UNCOV
48
            normalizationContext: [
UNCOV
49
                'groups' => ['json'],
UNCOV
50
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
51
                'skip_null_values' => true,
UNCOV
52
            ]
UNCOV
53
        ),
UNCOV
54
        new ErrorOperation(
UNCOV
55
            name: '_api_validation_errors_hydra',
UNCOV
56
            outputFormats: ['jsonld' => ['application/problem+json', 'application/ld+json']],
UNCOV
57
            links: [new Link(rel: 'http://www.w3.org/ns/json-ld#error', href: 'http://www.w3.org/ns/hydra/error')],
UNCOV
58
            normalizationContext: [
UNCOV
59
                'groups' => ['jsonld'],
UNCOV
60
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
61
                'skip_null_values' => true,
UNCOV
62
            ]
UNCOV
63
        ),
UNCOV
64
        new ErrorOperation(
UNCOV
65
            name: '_api_validation_errors_jsonapi',
UNCOV
66
            outputFormats: ['jsonapi' => ['application/vnd.api+json']],
UNCOV
67
            normalizationContext: [
UNCOV
68
                'disable_json_schema_serializer_groups' => false,
UNCOV
69
                'groups' => ['jsonapi'],
UNCOV
70
                'skip_null_values' => true,
UNCOV
71
                'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
UNCOV
72
            ]
UNCOV
73
        ),
UNCOV
74
    ],
UNCOV
75
    graphQlOperations: []
UNCOV
76
)]
77
#[ApiProperty(property: 'traceAsString', hydra: false)]
78
#[ApiProperty(property: 'string', hydra: false)]
79
class ValidationException extends RuntimeException implements ConstraintViolationListAwareExceptionInterface, \Stringable, ProblemExceptionInterface, HttpExceptionInterface, SymfonyHttpExceptionInterface
80
{
81
    private int $status = 422;
82
    protected ?string $errorTitle = null;
83
    private array|ConstraintViolationListInterface $constraintViolationList = [];
84

85
    public function __construct(string|ConstraintViolationListInterface $message = new ConstraintViolationList(), string|int|null $code = null, int|\Throwable|null $previous = null, \Throwable|string|null $errorTitle = null)
86
    {
UNCOV
87
        $this->errorTitle = $errorTitle;
58✔
88

UNCOV
89
        if ($message instanceof ConstraintViolationListInterface) {
58✔
UNCOV
90
            $this->constraintViolationList = $message;
58✔
UNCOV
91
            parent::__construct($this->__toString(), $code ?? 0, $previous);
58✔
92

UNCOV
93
            return;
58✔
94
        }
95

96
        trigger_deprecation('api_platform/core', '5.0', \sprintf('The "%s" exception will have a "%s" first argument in 5.x.', self::class, ConstraintViolationListInterface::class));
×
97
        parent::__construct($message ?: $this->__toString(), $code ?? 0, $previous);
×
98
    }
99

100
    /**
101
     * @deprecated
102
     */
103
    public function getErrorTitle(): ?string
104
    {
105
        return $this->errorTitle;
×
106
    }
107

108
    public function getId(): string
109
    {
UNCOV
110
        $ids = [];
34✔
UNCOV
111
        foreach ($this->getConstraintViolationList() as $violation) {
34✔
UNCOV
112
            $ids[] = $violation->getCode();
34✔
113
        }
114

UNCOV
115
        $id = 1 < \count($ids) ? CompositeIdentifierParser::stringify(identifiers: $ids) : ($ids[0] ?? null);
34✔
116

UNCOV
117
        if (!$id) {
34✔
UNCOV
118
            return spl_object_hash($this);
1✔
119
        }
120

UNCOV
121
        return $id;
33✔
122
    }
123

124
    #[Groups(['jsonld'])]
125
    #[ApiProperty(writable: false, initializable: false)]
126
    public function getDescription(): string
127
    {
UNCOV
128
        return $this->detail;
22✔
129
    }
130

131
    #[Groups(['jsonld', 'json', 'jsonapi'])]
132
    #[ApiProperty(writable: false, initializable: false)]
133
    public function getType(): string
134
    {
UNCOV
135
        return '/validation_errors/'.$this->getId();
34✔
136
    }
137

138
    #[Groups(['jsonld', 'json', 'jsonapi'])]
139
    #[ApiProperty(writable: false, initializable: false)]
140
    public function getTitle(): ?string
141
    {
UNCOV
142
        return $this->errorTitle ?? 'An error occurred';
56✔
143
    }
144

145
    #[Groups(['jsonld', 'json', 'jsonapi'])]
146
    #[ApiProperty(writable: false, initializable: false)]
147
    private string $detail;
148

149
    public function getDetail(): ?string
150
    {
UNCOV
151
        return $this->detail;
34✔
152
    }
153

154
    public function setDetail(string $detail): void
155
    {
UNCOV
156
        $this->detail = $detail;
34✔
157
    }
158

159
    #[Groups(['jsonld', 'json', 'jsonapi'])]
160
    public function getStatus(): ?int
161
    {
UNCOV
162
        return $this->status;
56✔
163
    }
164

165
    public function setStatus(int $status): void
166
    {
UNCOV
167
        $this->status = $status;
34✔
168
    }
169

170
    #[Groups(['jsonld', 'json', 'jsonapi'])]
171
    #[ApiProperty(writable: false, initializable: false)]
172
    public function getInstance(): ?string
173
    {
UNCOV
174
        return null;
34✔
175
    }
176

177
    #[SerializedName('violations')]
178
    #[Groups(['json', 'jsonld'])]
179
    #[ApiProperty(
UNCOV
180
        jsonldContext: ['@type' => 'ConstraintViolationList'],
UNCOV
181
        schema: [
UNCOV
182
            'type' => 'array',
UNCOV
183
            'items' => [
UNCOV
184
                'type' => 'object',
UNCOV
185
                'properties' => [
UNCOV
186
                    'propertyPath' => ['type' => 'string', 'description' => 'The property path of the violation'],
UNCOV
187
                    'message' => ['type' => 'string', 'description' => 'The message associated with the violation'],
UNCOV
188
                ],
UNCOV
189
            ],
UNCOV
190
        ]
UNCOV
191
    )]
192
    public function getConstraintViolationList(): ConstraintViolationListInterface
193
    {
UNCOV
194
        return $this->constraintViolationList;
58✔
195
    }
196

197
    public function __toString(): string
198
    {
UNCOV
199
        $message = '';
58✔
UNCOV
200
        foreach ($this->getConstraintViolationList() as $violation) {
58✔
UNCOV
201
            if ('' !== $message) {
36✔
UNCOV
202
                $message .= "\n";
5✔
203
            }
UNCOV
204
            if ($propertyPath = $violation->getPropertyPath()) {
36✔
UNCOV
205
                $message .= "$propertyPath: ";
36✔
206
            }
207

UNCOV
208
            $message .= $violation->getMessage();
36✔
209
        }
210

UNCOV
211
        return $message;
58✔
212
    }
213

214
    public function getStatusCode(): int
215
    {
UNCOV
216
        return $this->status;
34✔
217
    }
218

219
    public function getHeaders(): array
220
    {
UNCOV
221
        return [];
34✔
222
    }
223
}
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