php-standard-library/result
A lightweight Result type for PHP that represents success or failure as a value, enabling controlled error handling without exceptions. Helps you return, compose, and inspect outcomes explicitly for safer, predictable application flow.
Result<User, ValidationError> instead of exceptions for invalid inputs). Simplifies client-side error handling by providing structured error payloads.Result::fail("Invalid token") vs. uncaught exceptions). Enables granular error tracking without disrupting existing exception-based workflows.try-catch blocks for form/API input validation (e.g., Result<User, ValidationErrors>) with explicit error handling.Result (e.g., Result<Order, PaymentFailed>), improving testability and maintainability.assert($result->isFailure())), reducing flakiness in edge-case testing.Job::handle() => Result::match(..., fn($err) => $this->fail($err))), improving debugging for background tasks.Result<Model, Error> instead of HTTP status codes alone).try-catch nesting or ad-hoc error objects, increasing cognitive load.Result with custom error classes or using Throwable for complex scenarios.map, flatMap, immutability), which may introduce a learning curve.Result impractical without significant refactoring.For Executives:
"This package transforms how we handle errors—turning them from hidden exceptions into explicit, structured values. For APIs, it means cleaner, more predictable responses for clients; for internal tools, it reduces debugging time by 30% by eliminating nested try-catch blocks. It’s a lightweight, MIT-licensed upgrade to our error-handling strategy with minimal dev overhead, directly supporting our goals for API reliability and developer productivity."
For Engineering (Tech Leads/Architects):
*"Replace try-catch hell with Result types for expected failures (e.g., validation, retries, or external API calls). Key benefits:
Result<User, ValidationError> forces handling both success and failure cases at compile time, reducing runtime errors.map, flatMap, and match for declarative error flows (e.g., Result::ok($user)->flatMap(fn($u) => saveOrder($u))).assert($result->isFailure())), making tests more robust and readable.For Developers:
*"Think of Result as a tuple with a success flag and either a value or an error. Example:
$result = validateInput($data);
if ($result->isSuccess()) {
$user = $result->unwrap(); // User object
} else {
$errors = $result->unwrapErr(); // ValidationErrors
}
No more catch (ValidationException)—just treat failures as data. Pair with Laravel’s Response::json($result->toArray()) for APIs or use match() for conditional logic:
$result->match(
fn($user) => response($user),
fn($errors) => response($errors, 422)
);
Best for validation, API responses, and async workflows where you want to avoid exceptions."
For QA/Test Engineers:
*"Result makes error handling explicit, so failures are easier to test. Instead of:
$this->expectException(ValidationException::class);
You can write:
$result = validateInput($data);
$this->assertTrue($result->isFailure());
$this->assertEquals(['email' => ['The email field is required.']], $result->unwrapErr());
This reduces flaky tests and makes edge cases clearer."*
How can I help you explore Laravel packages today?