On Sun, Dec 14, 2025, at 12:02 PM, Yousha Aleayoub wrote:
> Hello,
>
> I’m submitting for discussion and vote a new PSR proposal to address a
> long-standing gap in PHP’s *error-handling* ecosystem:
>
> Standard Interfaces for Recoverable Errors and Operation Results
> *(Working title: PSR-XX Error and Result Interfaces)*
> *
> *
> *The problem*
> PHP *forces *developers to choose between two flawed patterns for
> non-exceptional failures:
>
> • Throwing exceptions for expected outcomes (like validation errors,
> cache misses) -> breaks control flow, hurts performance, and conflates
> recoverable vs. unrecoverable errors.
> • Returning ambiguous values (null, false, ['error' => ...]) →
> destroys type safety and forces brittle checks across the call stack.
> Frameworks and libraries reinvent this wheel constantly:
> • Laravel’s ValidationException
> • Symfony’s ConstraintViolationList
> • Guzzle’s TransferException + status codes
> • Custom Result<bool, string> classes in libraries...
> There is no interoperable, type-safe way to return structured,
> recoverable errors.
>
> *The Solution*
> This PSR will propose three minimal, zero-dependency interfaces:
>
> 1. ResultInterface: a sealed union for success/failure states
> 2. SuccessInterface: wraps a successful value
> 3. FailureInterface: wraps structured error data (code, message,
> context) and optionally a Throwable
> *Key features*
> • No exceptions required for expected failures!
> • Immutable, readonly objects
> • Pattern-matchable via isSuccess()/isFailure()
> • Composable with PSR-3 (logging), PSR-11 (containers), *and async
> runtimes*
> • Zero runtime overhead – pure interfaces, no DI or middleware
> Thanks for your time.
Hi Yousha.
What you're describing is a user-space Result type. That's been discussed a few times throughout the years in PHP.
Worth reading on this topic:
https://www.garfieldtech.com/blog/much-ado-about-null
The main problem is that, since PHP lacks generics, using an abstracted "result" or "failure" interface means you lose type information for what the success value is. It could be somewhat emulated in PHPStan docblocks, but FIG generally tries to avoid relying on that as a solution. That's one reason you see so many one-off list types and validation error types: It would be great to not need that, but without generics, we kinda do need that.
Also, there is runtime overhead. The actual result objects that wrap the underlying value would add, at least, a method call for extracting the success value.
I'm not sure this is a great thing to standardize and push without generics. Had we those, I'd be all over this. :-)
For now, the "naked Either" approach described in the blog above is the least-bad solution I have found.
--Larry Garfield