Skip to content
This repository was archived by the owner on Sep 22, 2025. It is now read-only.

Commit 993ebcb

Browse files
committed
Improve UrlValidationError generation
1 parent 316ce76 commit 993ebcb

File tree

2 files changed

+25
-48
lines changed

2 files changed

+25
-48
lines changed

src/WhatWg/Url.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
final class Url
2828
{
2929
private WhatWgURL $url;
30-
private ValidationErrorLog $logger;
30+
private ValidationErrorLogger $logger;
3131

3232
/**
3333
* @param array<int, UrlValidationError> $errors
@@ -50,10 +50,11 @@ public static function parse(string $uri, ?string $baseUrl = null, array &$error
5050
*/
5151
public function __construct(string $uri, ?string $baseUrl = null, array &$softErrors = [])
5252
{
53-
$this->logger = new ValidationErrorLog();
53+
$this->logger = new ValidationErrorLogger();
5454
$options = ['logger' => $this->logger];
5555

5656
try {
57+
$this->logger->reset();
5758
$this->url = new WhatWgURL($uri, $baseUrl, $options);
5859
} catch (Exception $exception) {
5960
throw new InvalidUrlException(
Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,77 +15,66 @@
1515

1616
use OutOfBoundsException;
1717
use Psr\Log\AbstractLogger;
18+
use Psr\Log\LogLevel;
1819
use Stringable;
1920

2021
use function is_scalar;
2122
use function is_string;
22-
use function strtr;
2323

2424
/**
2525
* @internal
2626
*
2727
* This class allows accessing WHATWG errors
2828
* emitted by \Rowbot\URL\URL and convert them
29-
* into \Uri\WhatWg\UrlValidationError instances
29+
* into an array of \Uri\WhatWg\UrlValidationError instances
3030
*
3131
* This class IS NOT PART of the RFC public API
32-
* but is needed to implement the polyfill.
32+
* but is needed to implement the polyfill against
33+
* the \Rowbot\URL\URL package
3334
*/
34-
final class ValidationErrorLog extends AbstractLogger
35+
final class ValidationErrorLogger extends AbstractLogger
3536
{
36-
/** @var array<int, UrlValidationError> */
37-
private array $recoverableErrors = [];
38-
/** @var array<int, UrlValidationError> */
37+
/** @var list<UrlValidationError> */
3938
private array $errors = [];
4039

40+
public function reset(): void
41+
{
42+
$this->errors = [];
43+
}
44+
4145
/**
42-
* @return array<int, UrlValidationError>
46+
* @return list<UrlValidationError>
4347
*/
4448
public function errors(): array
4549
{
4650
return $this->errors;
4751
}
4852

4953
/**
50-
* @return array<int, UrlValidationError>
54+
* @return list<UrlValidationError>
5155
*/
5256
public function recoverableErrors(): array
5357
{
54-
return $this->recoverableErrors;
58+
return array_values(
59+
array_filter(
60+
$this->errors,
61+
fn (UrlValidationError $error): bool => !$error->failure
62+
)
63+
);
5564
}
5665

5766
public function log(mixed $level, string|Stringable $message, array $context = []): void
5867
{
5968
$errorContext = $context['input'] ?? null;
60-
if ($errorContext instanceof Stringable) {
69+
if (is_scalar($errorContext) || $errorContext instanceof Stringable) {
6170
$errorContext = (string) $errorContext;
6271
}
6372

6473
if (!is_string($errorContext)) {
6574
return;
6675
}
6776

68-
$validationError = new UrlValidationError(
69-
$errorContext,
70-
$this->messageMapper($this->interpolate($message, $context)),
71-
'warning' === $level
72-
);
73-
74-
$this->errors[] = $validationError;
75-
if ('notice' === $level) {
76-
$this->recoverableErrors[] = $validationError;
77-
}
78-
}
79-
80-
public function reset(): void
81-
{
82-
$this->recoverableErrors = [];
83-
$this->errors = [];
84-
}
85-
86-
private function messageMapper(string $message): UrlValidationErrorType
87-
{
88-
return match ($message) {
77+
$type = match ((string) $message) {
8978
// recoverable errors
9079
'special-scheme-missing-following-solidus' => UrlValidationErrorType::SpecialSchemeMissingFollowingSolidus,
9180
'invalid-URL-unit' => UrlValidationErrorType::InvalidUrlUnit,
@@ -117,20 +106,7 @@ private function messageMapper(string $message): UrlValidationErrorType
117106
'port-invalid' => UrlValidationErrorType::PortInvalid,
118107
default => throw new OutOfBoundsException('unknown error type:'.$message),
119108
};
120-
}
121-
122-
/**
123-
* @param array<array-key, mixed> $context
124-
*/
125-
private function interpolate(string|Stringable $message, array $context = []): string
126-
{
127-
$replacements = [];
128-
foreach ($context as $key => $val) {
129-
if (is_scalar($val) || $val instanceof Stringable) {
130-
$replacements['{'.$key.'}'] = $val;
131-
}
132-
}
133109

134-
return strtr((string) $message, $replacements);
110+
$this->errors[] = new UrlValidationError($errorContext, $type, LogLevel::WARNING === $level);
135111
}
136112
}

0 commit comments

Comments
 (0)