Skip to content

Add an opt-in best-effort throwable handler aggregate #6

Closed

Description

@coisa

Delivery track and decision

The owner approved this separate, compatible 2.x minor, then merged PR80 at 2026-10-16T05:30:13Z, producing 1d31a0c3cafa0fcda495961951e216b0b163f4e0. The PR natively closed this issue as COMPLETED. The two new classes shipped in v2.4.0 and remain present in current master/v2.4.1. No agent performed the merge or release. The existing fail-fast aggregate, defaults, factories and typed ErrorHandler constructor remain unchanged.

This supersedes the earlier major-snapshot investigation below: the current 2.x ErrorHandler has no general reporter-failure reentry guard, and its middleware delegates rendering to the existing response factory. This feature changes neither boundary. Broader lifecycle/HTTP changes remain in the major roadmap.

Approved contract

  • Add Handler\BestEffortThrowableHandlerAggregate(ThrowableHandlerInterface ...$handlers) with a fixed, explicitly supplied reporter list.
  • On each handleThrowable($original) call, attempt every constructor slot once, in order, with the identical original Throwable. Duplicate slots are deliberate separate attempts.
  • Catch reporter Throwable failures during that single pass. If any fail, including partial success, throw one Exception\AggregateReportingException after all attempts. Zero reporters and all-success calls return normally.
  • The exception receives the original, one required reporter failure and remaining variadic failures. getOriginalThrowable() returns the original object; getFailures() returns the nonempty, ordered list of identical reporter failure objects. The previous cause is the original. Its fixed summary message does not concatenate diagnostics; the exception and previous cause remain private diagnostic data.
  • No retries, automatic recursive delivery, reentry guard, observer, factory, discovery, dependencies or configuration DSL. Applications own terminal handling and durable delivery.

The existing ThrowableHandlerAggregate stays fail-fast. Keeping both policies in a future major is a recommendation, not a separately approved major redesign. Bare-callable ErrorHandler constructor inputs remain major work.

Acceptance

  • Agree on the aggregate-exception terminal policy and additive 2.x scope.
  • Implement the two opt-in classes with English PHPDoc and PHP 7.4-compatible syntax, proposed in PR80.
  • Add focused PHPUnit tests for inert construction, zero/one/many reporters, first/middle/last/all failures, partial success, Throwable kinds, object identities, ordered failures, deliberate duplicates, named variadic arguments and independent repeated invocations.
  • Preserve fail-fast/default behavior and document that native registration, shutdown and legacy HTTP behavior gain no new recovery/redaction guarantees.
  • Align a runnable synthetic example, README, API/container/HTTP guidance, static source parity and the portable coisa-error-handler skill.
  • Include a minor Changeset and verify focused minimum/modern PHP, ordinary quality checks, clean no-dev/archive loading and exact-head hosted CI. PHP CI38854392241 passes14jobs at the PR head;22checks succeed with17expected skips. Local full quality:232tests/746assertions; focused7.4/8.5:14/55; both new classes100%, overall95.91%→96.14%.

The completed implementation checks above belong to candidate cd379c1f; the later owner merge and published release are recorded at the top. Native Closes #6 linked PR80 and closed the issue. Released-adapter wording was corrected by PR83, and the complete source-checked recipe was added by PR86, both released in 2.4.1. This reconciliation adds no feature, new publication or retry policy.

No real logger, network sink or production data is required. A return from a reporter is not proof of transport delivery. Partial reporter output and the aggregate exception must not be treated as a public response body.

Related: compatible maintenance, major API/lifecycle roadmap, logging, filtering.

Activity

  1. changed the title [-]Design an opt-in best-effort throwable handler aggregate[/-] [+]Add an opt-in best-effort throwable handler aggregate[/+] on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions