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 type enforces explicit error handling via Ok/Err variants, aligning well with Laravel’s growing adoption of functional patterns (e.g., collect(), tap()). This contrasts with Laravel’s traditional exception-based error handling, offering an alternative for domain-driven design (DDD) or bounded contexts where errors are part of the business logic (e.g., validation, external API responses).map(), flatMap()) integrate seamlessly with Laravel’s service containers and middleware pipelines, enabling declarative error flows (e.g., Result::fromCallable(fn() => Model::findOrFail($id))->map(...)).Validator::fails() checks with Result::Err() for structured responses.Response facade (e.g., Result::match(fn($data) => response($data), fn($err) => response($err, 400))).Bus::dispatch(new ProcessOrder($order))->then(fn($result) => $result->match(...))).Result::fromThrowable()).expectException() with expect(Result::err()) assertions, improving test readability.Result for certain use cases. Risk mitigated by:
@returns Result<Model, ValidationError>) and IDE plugins to highlight Result-returning methods.Result instances for repeated operations).Http/Validation components lack built-in Result support (e.g., Validator::validate() returns bool). Workaround: Wrap calls in Result::fromCallable().Err variants (e.g., Result::match(..., fn($err) => Log::error($err))).Result?try-catch in API controllers with Result::match() for HTTP responses.Err carry domain-specific error types (e.g., PaymentFailed) or remain generic?Result::fromThrowable() vs. custom adapters).Result usage in specific contexts?Result improve test coverage for edge cases (e.g., Result::err(new RuntimeException()))?Result<Model, string>) for type safety.Illuminate\Support\LazyCollection).spatie/laravel-activitylog: Use Result to log failures explicitly (e.g., Result::match(..., fn($err) => Activity::log($err))).fruitcake/laravel-cors: Handle CORS errors as Result::Err() for consistent responses.spatie/laravel-query-builder: Replace try-catch in custom queries with Result::fromCallable().Result in a single feature (e.g., API endpoint for user creation).try-catch.// Before
try {
$user = User::create($data);
return response($user);
} catch (ValidationException $e) {
return response($e->errors(), 422);
}
// After
$result = Result::fromCallable(fn() => User::create($data));
return $result->match(
fn($user) => response($user),
fn($err) => response($err->errors(), 422)
);
Result to domains with complex error flows (e.g., payment processing, external API calls).ResultAwareController trait for consistency.Cache::get(), Mail::send()) in Result adapters.Result::fromCallable(fn() => Cache::get('key'))->unwrapOrThrow();
Result (e.g., Result::fromCallable(fn() => Auth::user())).Result to short-circuit requests early (e.g., Result::match($authResult, ..., fn($err) => abort(401, $err))).Result to the container for dependency injection:
$this->app->bind(Result::class, fn() => new Result());
Result to propagate errors in async workflows (e.g., Bus::dispatch(new ProcessOrder($order))->then(fn($result) => $result->match(...))).throw new RuntimeException() with return Result::err(new RuntimeException()).Result with Eloquent queries (e.g., Result::fromCallable(fn() => User::where(...)->first())).Result forces error handling upfront, reducing runtime surprises.Result::flatMap() for sequential operations).Result types (e.g., "Show possible Err variants").Result usage patterns (e.g., "Always use match() for HTTP responses").Err are clearer than nested try-catch.Result chains may need custom logging (e.g., Result::tap(fn($result) => Log::debug($result))).Result (e.g., Result::fromCallable(fn() => Stripe::charges()->create($params))).Result::Ok() for idempotent operations (e.g., Result::fromCallable(fn() => Cache::remember(...))).Result with Laravel Queues to handle job failures explicitly (e.g., Job::handle() => Result::match(..., fn($err) => $this->fail($err))).spatie/async for Result-aware parallel tasks.Result is stateless; scales identically to exception-based code.| Failure Scenario | Traditional Exception Handling | **Result-Based Handling
How can I help you explore Laravel packages today?