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

Technical Evaluation

Architecture fit. graham-campbell/result-type is a framework-agnostic value object providing a Result base type with Success (value) and Error (reason) variants. Its value to a Laravel organization is architectural rather than functional: it converts failure from a thrown side effect into a returned value, which is valuable precisely where failure is an expected business outcome rather than an exceptional one — payment declines, third-party API rejections, parsing/validation of external payloads, multi-step workflows with partial success. It is explicitly not a replacement for Laravel's exception-driven core (HTTP kernel, FormRequest validation, middleware, queue retries, Eloquent). The defensible position for stakeholders is a complementary pattern confined to the service/domain layer, with translation adapters at the edge. If the team cannot state and enforce that boundary in a single paragraph, the package will introduce a second competing error-handling paradigm and reduce clarity rather than improve it.

Integration feasibility. Installation cost is effectively zero — composer require graham-campbell/result-type:^1.1, no service provider, no config publishing, no migrations, no runtime hooks, no framework coupling to track across Laravel upgrades. The real cost is convention, adapter code, and refactoring effort:

  • Controllers, middleware, jobs, and Eloquent all speak exceptions; using Result in those layers requires translation shims, which must be written before the first Result ships.
  • Static analysis must understand the Success/Error hierarchy (@return Result<int, ErrorCode>) to be useful; without a configured rule or lint gate, unwrapped Error branches will slip through review.
  • Greenfield service classes are the cheapest and lowest-risk entry point. Retrofitting existing controllers, models, or job payloads is not worth the effort and should be declared out of scope in writing.

Technical risk. Moderate, and predominantly organizational rather than technical:

  • Ecosystem validation is thin. Zero dependents and a composite score of 3.6 indicate limited real-world usage, particularly inside Laravel applications. The codebase is small enough to audit and fork in an afternoon, which mitigates abandonment risk but does nothing to mitigate misuse risk.
  • Language ergonomics. PHP lacks exhaustive pattern matching, structural equality (new Success(1) === new Success(1) is false), and destructuring. A carelessly unwrapped Error becomes a runtime failure — the exact failure mode the pattern exists to prevent. This is a discipline risk, not a package defect, and it is the single most likely cause of a failed pilot.
  • Paradigm fragmentation. Mixing exceptions and Result within one call stack produces confusing stack traces and inconsistent error contracts across teams. Every additional team that adopts with a different convention compounds this.
  • Maintenance risk is genuinely low. MIT license, disciplined changelog and release cadence, prompt PHP version tracking (7.2.5 through 8.6), documented security policy, and a Tidelift commercial support path. Bus factor is one maintainer, but the surface area is small.
  • Dependency note. The package is not a true leaf: v1.2.0 requires phpoption ≥1.10. It is a small, same-author transitive surface — pin and audit the lock file rather than treating it as zero-dependency.

Key questions to resolve before approval.

  1. Which single bounded context adopts this first, and what is explicitly out of scope? (Recommendation: one external-API or payment client service; never controllers, models, or queued jobs.)
  2. What is the Error taxonomy — string codes, backed enums, or typed error objects — and who owns its evolution?
  3. Where does the exception→Result conversion live for third-party SDKs that throw? Who reviews that adapter, and is it tested against both branches?
  4. Will PHPStan/Psalm or an equivalent CI gate flag ignored or unwrapped Result values? Without a mechanical gate, the convention will erode within two sprints.
  5. What is the success metric? Suggested: unhandled-exception incidents in the target module, mean time to diagnose failures, and adoption coverage within the declared boundary.
  6. Is leadership willing to accept a scoped, conditional pilot rather than an org-wide standard? A package at 3.6 with zero dependents should not be mandated globally on the strength of a README.

TPM recommendation. Conditional buy for a single bounded pilot: one domain, one named owner, one quarter, with a written convention document and a go/no-go review at the end. Reject "adopt everywhere" outright.

Integration Approach

Stack fit. Compatible with any Composer-based PHP stack on PHP 7.2.5–8.6, including current Laravel releases. It has no framework integration points by design — a strength (no coupling, no upgrade drag, no Laravel version matrix to maintain) and simultaneously a weakness (no guardrails, no container bindings, no opinion about where it belongs). It fits service classes, domain objects, HTTP client wrappers, and console command handlers. It does not fit controller return types, Eloquent model attributes, middleware signatures, or job payloads without bespoke adapters.

Migration path. Do not migrate existing exception-based code. Use a strangler-style, boundary-first rollout:

  1. Select one fallible operation with unambiguous success/failure semantics and a low blast radius.
  2. Introduce Result only inside that service; its signature (Result<T, E>) becomes the explicit contract.
  3. Build both adapters on day one — Result → HTTP response in the controller, and Result → domain exception where the framework insists on one.
  4. Codify the rule: Result is internal to the service layer; exceptions remain the language of the framework edge.
  5. Extend to a second domain only after the pilot review passes its metrics.

Compatibility considerations.

  • Use PHPDoc generics to keep static analysis useful on PHP 7.x; native union types require PHP 8+. Confirm the minimum supported PHP of the target service before choosing a syntax style.
  • Pin ^1.1 and verify the resolved phpoption version in the lock file, particularly if a PHP 8.4/8.5/8.6 upgrade is in flight.
  • Never serialize a Result across queues, caches, or API responses — convert to a plain DTO, enum, or exception at the boundary. This is the most common design mistake with these types.
  • Check for overlap with any error-handling or monad-style library already in the dependency tree. Conflict is unlikely; duplication and competing conventions are the more probable failure.

Sequencing.

  • Weeks 1–2 — Discovery and spike. Branch-level composer require, spike one service, draft the convention one-pager with adapter examples, confirm CI and static analysis behave. Deliverable: a decision-ready prototype, not production code.
  • Weeks 3–4 — Pilot implementation. Ship the pilot domain with tests asserting both Success and Error branches, not just happy paths. Add the static-analysis rule or a lint checklist to CI in the same pull request.
  • Weeks 5–8 — Operate and measure. Track incidents, time-to-diagnose, code-review friction, and developer sentiment. Collect concrete examples for training material.
  • End of quarter — Go/no-go. Decide to formalize, extend to a second domain, or retire the pattern. Make the call on data and document it either way.
  • Hard dependency: training and the convention document must land before any expansion. Do not sequence breadth ahead of the pilot review.

Operational Impact

Maintenance. External maintenance burden is close to zero: small, stable, permissively licensed, and prompt on PHP releases. The ongoing cost is internal convention upkeep — error taxonomy, adapter code, static-analysis configuration, and reviewer discipline. Assign a named tech lead as pattern owner; without one, usage will drift into per-team variants within a quarter and the pattern's value will invert.

Support. Community support through GitHub with a documented security disclosure process; commercial support via Tidelift if procurement requires an SLA or indemnity. Given the size of the codebase, a fork-and-vendor contingency is realistic and inexpensive. Record both the support model and the fork trigger conditions in the risk register — do not assume enterprise-grade backing unless the Tidelift subscription is actually purchased.

Scaling. Runtime overhead is negligible and will not register against database or network latency; this is not a performance decision. The scaling risk is cognitive. The pattern scales well when confined to a declared boundary and poorly when it spreads opportunistically — inconsistent Result usage becomes a permanent code-review tax that grows with headcount. Mitigate with a one-page internal standard, in-repo reference examples, and a reference implementation the team can copy.

Failure modes. Rank the risks the team should plan for:

  1. Boundary leak — a Result reaches a controller, job, or JSON response and consumers mishandle it. Detection: code review plus a static-analysis rule; blast radius is a runtime error at the worst possible moment.
  2. Ignored Error branch — the pattern silently degrades into a verbose false. Detection: require both-branch test coverage and enable a static-analysis rule that flags discarded results.
  3. Taxonomy sprawl — each team invents its own error codes, so Error values are untranslatable across services. Detection: single owned enum/type per bounded context, reviewed at the architecture forum.
  4. Paradigm collision — mixed exception/Result call stacks produce unreadable traces and inconsistent API error contracts. Detection: adapter code review and a documented translation table from Error to HTTP status.
  5. Silent abandonment — the pilot ships, the owner rotates off, and half-migrated code stays behind. Detection: explicit rollback plan written at pilot start, plus a scheduled review date.

Ramp-up. Low in absolute terms — the API is small and a competent Laravel developer can learn it in a day. The expensive part is the discipline, not the syntax: developers must internalize when to return a Result versus throw, how to write both adapters, and how to test the Error path. Budget roughly half a day of onboarding per developer plus one to two weeks of pair-reviewed pilot work for the first team, and expect code-review friction to spike briefly before settling. Do not onboard a second team until the first team's convention document has been validated by real code.

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