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 aligns with Laravel’s growing adoption of functional programming patterns (e.g., collect(), tap()), offering a type-safe alternative to exceptions for expected failures. This is particularly valuable in Laravel’s service layer, API responses, and domain logic where explicit error handling improves predictability.Result::match($authResult, ..., fn($err) => abort(401))).Validator::fails() with structured Result::Err(ValidationErrors), improving API response consistency.Bus::dispatch(new ProcessOrder($order))->then(fn($result) => $result->match(...))).Response facade (e.g., Result::match(fn($data) => response($data), fn($err) => response($err, 400))).assert($result->isFailure())).Result::fromThrowable()).Either monads).Result return types).Result for expected failures (e.g., validation, API responses) instead of exceptions. Mitigation:
Result usage guide with examples for common Laravel patterns (e.g., validation, HTTP responses).Validator, Http, and Queue components lack built-in Result support. Workaround: Wrap calls in Result::fromCallable().Err variants (e.g., Result::match(..., fn($err) => Log::error($err))).Result::Ok() for idempotent operations).Result? Example: Replace try-catch in API controllers with Result::match() for HTTP responses.Err carry domain-specific error types (e.g., PaymentFailed) or remain generic (e.g., string)?Result::fromThrowable() for direct conversion.ValidatorAdapter::validateAsResult()).Result usage in specific contexts (e.g., @returns Result<User, ValidationError>)?Result improve test coverage for edge cases (e.g., Result::err(new RuntimeException()))?Result overhead (e.g., method calls) is unacceptable? Consider caching or lazy evaluation.Result<Model, string>) for type safety.Illuminate\Support\LazyCollection).Validator::fails() with Result::Err() for structured responses.Result::match() to map Ok/Err to Response objects.Result through job handling (e.g., Job::handle() => Result::match(...)).Spatie/Laravel-Logging to log Err variants.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:
Validator::validate() in Result.Result::fromCallable() for HTTP clients (e.g., Guzzle).try-catch in services with Result chains.ResultAwareController trait for consistency.Result adapters:
Result::fromCallable(fn() => Model::findOrFail($id)).Result::fromCallable(fn() => Cache::get('key')).Result::fromCallable(fn() => Mail::send($mailable)).Result to the container for dependency injection:
$this->app->bind(Result::class, fn() => new Result());
Result:
$userResult = Result::fromCallable(fn() => Auth::user());
$userResult->match(
fn($user) => $user->name,
fn($err) => "Guest"
);
Result to short-circuit requests:
public function handle($request, Closure $next) {
$authResult = Result::fromCallable(fn() => Auth::user());
return $authResult->match(
fn($user) => $next($request),
fn($err) => abort(401, $err->getMessage())
);
}
Result to the container for dependency injection:
$this->app->singleton(Result::class, fn() => new Result());
try-catch in API controllers with Result::match().Result to propagate errors in async workflows:
Bus::dispatch(new ProcessOrder($order))
->then(fn($result) => $result->match(
fn($order) => Log::info("Order processed"),
fn($err) => Log::error("Order failed: " . $err)
));
throw new RuntimeException() with return Result::err(new RuntimeException()).Result with Eloquent queries:
$userResult = Result::fromCallable(fn() => User::where('email', $email)->first());
Result forces error handling upfront, reducing runtime surprises (e.g., uncaught exceptions).Result::flatMap() for sequential operations).assert($result->isFailure())), improving test coverage.How can I help you explore Laravel packages today?