ValidationError
extends NetworkError
in package
`400`/`422` on the §27 management surface — CONTRACT.md §27.4 rule 7.
Extends NetworkError, inherited from §2's own 400 row. That placement has one
consequence worth naming: §16's retry helper retries NetworkError, so without
care a body the server has already rejected would be sent three times. §27.4 rule 8
(only GET is retried) and the retryable predicate on
RetryPolicy::execute() are what stop that.
Table of Contents
Properties
- $fields : array<string|int, mixed>
- $retryAfterMs : float|null
- A server-supplied `Retry-After` hint in milliseconds (CONTRACT.md §16.1), `null` when the response carried none.
Methods
- __construct() : mixed
- fromException() : self
- Builds a NetworkError from a caught transport exception (socket/TLS/DNS/timeout failure). The caught exception's own message is defensively regex-sanitized in case a lower-level exception echoed a sensitive header verbatim; the exception itself is never stored as a cause (see class doc).
- fromMessage() : self
- Builds a `NetworkError` from a plain message with no live response or exception to redact — e.g. a malformed/short response BODY already decoded into a plain array by the caller, with no `ResponseInterface`/headers left to sanitize.
- fromResponse() : self
- Builds a NetworkError from a live PSR-7 response. Header NAMES are preserved for debuggability; VALUES of `Set-Cookie`/`Authorization`/`Cookie` are replaced with `[SENSITIVE]` before the summary string is built. The `$response` argument itself is never stored — only the resulting sanitized string survives past this method.
Properties
$fields read-only
public
array<string|int, mixed>
$fields
= []
$retryAfterMs
A server-supplied `Retry-After` hint in milliseconds (CONTRACT.md §16.1), `null` when the response carried none.
public
float|null
$retryAfterMs
= null
A parsed duration, never the raw header text, so the sanitization discipline this class exists to enforce is untouched: a float cannot carry a token, a URL, or anything else a header might. §16 honors it as a floor on the backoff — the server is stating when it will be ready, so retrying sooner is not permitted.
Methods
__construct()
public
__construct(string $message[, array<int, FieldError> $fields = [] ]) : mixed
Parameters
- $message : string
-
Human-readable summary of the rejection.
- $fields : array<int, FieldError> = []
-
Per-field complaints; empty when the server sent none.
fromException()
Builds a NetworkError from a caught transport exception (socket/TLS/DNS/timeout failure). The caught exception's own message is defensively regex-sanitized in case a lower-level exception echoed a sensitive header verbatim; the exception itself is never stored as a cause (see class doc).
public
static fromException(Throwable $exception[, string $context = 'Transport error' ]) : self
Parameters
- $exception : Throwable
- $context : string = 'Transport error'
Return values
selffromMessage()
Builds a `NetworkError` from a plain message with no live response or exception to redact — e.g. a malformed/short response BODY already decoded into a plain array by the caller, with no `ResponseInterface`/headers left to sanitize.
public
static fromMessage(string $message) : self
$message still passes through self::sanitizeMessage() as defense in
depth, matching self::fromException()'s own discipline.
Parameters
- $message : string
Return values
selffromResponse()
Builds a NetworkError from a live PSR-7 response. Header NAMES are preserved for debuggability; VALUES of `Set-Cookie`/`Authorization`/`Cookie` are replaced with `[SENSITIVE]` before the summary string is built. The `$response` argument itself is never stored — only the resulting sanitized string survives past this method.
public
static fromResponse(ResponseInterface $response[, string $context = 'HTTP error' ]) : self
Parameters
- $response : ResponseInterface
- $context : string = 'HTTP error'