Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Result Type Laravel Package

graham-campbell/result-type

Result Type is a PHP implementation of the result type, maintained by Graham Campbell. It offers a clean way to represent success or failure values instead of exceptions. Install via Composer with graham-campbell/result-type ^1.1; requires PHP 7.2.5-8.6. MIT licensed.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy vs. borrow for error modeling. When a roadmap item hinges on making failure states explicit — payment declines, third-party API rejections, KYC/verification outcomes, multi-step onboarding with partial success — this package answers "do we build a result type ourselves?" with a cheap "borrow" (MIT, ~zero install cost, small enough to fork). The PM decision is whether the capability is worth adopting as a convention rather than writing bespoke error objects per team.
  • Reliability and supportability roadmaps. Adopting Result at the service layer is a lever for reducing "unhandled exception" incidents and improving mean time to diagnose failures. That maps directly to reliability OKRs and on-call toil reduction, and gives the PM a measurable claim (incidents in the target module, time-to-diagnose) rather than a stylistic one.
  • Scoping a pilot as a product bet. Because ecosystem validation is thin (zero dependents, composite score 3.6), the right PM move is a bounded, time-boxed pilot in one domain — one named owner, one quarter, written convention, explicit go/no-go. This is a classic "small reversible bet" decision and should be framed to leadership as such, not as a platform standard.
  • Architecture governance / tech-debt prioritization. Deciding where the pattern is allowed (service and domain layer) and where it is forbidden (controllers, Eloquent models, middleware, queued job payloads, serialized API responses) is a product-visible boundary decision: it determines onboarding cost, review friction, and how fast new engineers can read the codebase. Also informs sequencing: training and the convention doc must land before any expansion beyond the pilot.
  • Hiring, onboarding, and DX investment. The package adds a paradigm (returned failures) alongside Laravel's exception-driven core. That's a real onboarding and cognitive-load cost. It justifies (or de-prioritizes) investment in a one-page internal standard, in-repo reference implementation, and CI static-analysis gates that flag ignored Result values.
  • Buying commercial support. Tidelift availability is a procurement decision — relevant if the domain adopting it is revenue-critical and needs an SLA or indemnity. Low cost, low urgency, but it belongs in the risk register with fork triggers.
  • Explicit non-goals. This is not a performance initiative (overhead is negligible) and not a Laravel integration (no service provider, no config, no migrations). PMs should reject framing it as "modernizing the stack" — it's an error-contract decision scoped to one bounded context.

When to Consider This Package

Consider it when:

  • A feature has failure as an expected business outcome, not an exceptional one: payment authorization declines, third-party API rejections, external payload parsing/validation, multi-step workflows with partial success. Callers genuinely need to handle both branches.
  • You have or are creating a service/domain layer where contracts can be expressed as Result<T, E> and adapted at the edges.
  • You can name a single bounded context and a single owner for a quarter-long pilot, with a written error taxonomy (string codes, backed enums, or typed error objects) and adapter examples for exception→Result and Result→HTTP response.
  • You will enforce it mechanically: PHPStan/Psalm configured to flag ignored or unwrapped Result values in CI. Without that gate, the convention erodes within two sprints.
  • You're on any Composer-based PHP stack in the 7.2.5–8.6 range and want zero framework coupling, zero upgrade drag, and no Laravel-version matrix to maintain.
  • You're greenfield in the target service. Retrofitting existing controllers, models, or job layers is explicitly out of scope — the refactor cost buys nothing.
  • Maintenance posture matters and you want MIT, a disciplined changelog and release cadence, prompt PHP-version tracking (8.3–8.6), a documented security process, and a plausible fork-and-vendor contingency.

Look elsewhere (or say no) when:

  • The proposal is "adopt everywhere" or an org-wide standard. A package at this adoption level should not be mandated globally on the strength of a README.
  • The team can't articulate and enforce the exception-vs-Result boundary. Mixed paradigms in one call stack produce confusing traces and inconsistent error contracts — strictly worse than the status quo.
  • The need is really Laravel-shaped: HTTP validation, middleware, queue retries, Eloquent. Those layers speak exceptions; translate at the edge instead.
  • There's no appetite for the internal cost — error taxonomy ownership, adapter code, static-analysis config, reviewer discipline. In that case the package is free and the convention is not.
  • You'd be adding a second error-handling/monad library on top of one already in the dependency tree. Duplication is the more probable failure than conflict.
  • The intended use is serializing Result across queues, caches, or API responses, or relying on it as a "no-throw" guarantee. PHP lacks exhaustive matching and structural equality (new Ok(1) === new Ok(1) is false), so a carelessly unwrapped error becomes exactly the runtime failure the pattern exists to prevent.
  • You need enterprise-grade backing without buying Tidelift. Bus factor is one maintainer; mitigated by tiny surface area, but do not assume an SLA you haven't purchased.
  • Note the non-leaf dependency: phpoption (≥1.10 in v1.2.0). Pin and audit the lock file rather than treating this as zero-dependency.

How to Pitch It (Stakeholders)

For executives — the one-paragraph version:

We're proposing a small, reversible pilot, not a platform mandate. Laravel handles unexpected failures well, but it treats expected failures — a declined card, a rejected partner API call — the same as bugs. A result type lets those code paths return an explicit success-or-failure value that must be handled, which makes failure behavior visible in code review and easier to diagnose in production. The package is free, MIT-licensed, tiny, adds no infrastructure, and can be forked in an afternoon if we ever needed to. We'd run it for one quarter in one domain with one owner, measure incident rate and time-to-diagnose, and decide on data. Cost: roughly one engineer's part-time effort for a quarter, plus a one-page convention doc and a CI check. Risk: the main one isn't the software — it's that the pattern spreads informally and creates a second, competing way of handling errors.

For engineering leadership — why it's safe to try:

  • Install is a single composer require; no service provider, no config, no migrations, no runtime hooks. Removal is equally cheap.
  • Strictly scoped: Result lives inside the service layer. Controllers, FormRequests, middleware, jobs, and Eloquent keep speaking exceptions. We build both adapters (Result→HTTP, Result→exception) on day one so the boundary is real and enforced, not aspirational.
  • We will not migrate existing code. Strangler-style, boundary-first, greenfield service classes only.
  • We will not serialize Result across queues, caches, or API responses — convert to a DTO, enum, or exception at the edge. This is the most common design mistake with these types and our convention doc will say so explicitly.
  • CI enforces the convention via static analysis; both branches (Ok and Err) get tests, not just happy paths.
  • Maintenance risk is genuinely low: disciplined changelog and releases, prompt PHP 8.3–8.6 tracking, documented security policy, Tidelift available if we need an SLA. Single maintainer, but the surface is small enough to vendor.
  • What we're actually asking for: approval to run a scoped pilot with a written convention and a go/no-go review at quarter end — with a real option to retire the pattern if the data doesn't support it.

For the pilot team — the working agreement (pitch this as the guardrails that make it work):

  • One domain, one named pattern owner, one quarter.
  • Pick one fallible operation with unambiguous success/failure semantics and low blast radius, ideally a payment or external-API client.
  • Write the error taxonomy down first (string codes, enums, or typed error objects) and name who owns its evolution.
  • Adapters on day one; Result never crosses the service boundary.
  • Success metrics agreed up front: unhandled-exception incidents in the target module, mean time to diagnose failures, code-review friction, adoption coverage inside the declared boundary, developer sentiment.
  • Go/no-go at quarter end: formalize, extend to a second domain, or retire — and document the decision either way.

The headline to lead with: this is a conditional yes to a bounded experiment, not a vote for a new house style. The cheap install is the least interesting part; the thing we're actually buying is a clearer, measurable error contract in one revenue-relevant domain — and the discipline to keep it there.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource