Repository navigation
Add an opt-in direct PSR-3 throwable reporter #4
Description
Delivered status
This opt-in 2.x feature is complete. Owner coisa merged PR69 at a9b6c09bdd0ccbf7cee3691615bfd637eb64a2c1; that PR natively closed this issue. Handler\LogThrowableHandler shipped in v2.2.0 and remains present in current master/v2.4.1.
The implementation preserves PHP 7.4, existing discovery/defaults and the same Throwable in PSR-3 exception context, with focused unit tests, runnable logging example, full PHPDoc and matching guides/site/consumer skill. Diagnostic transport remains application-owned. PR83 corrected stale pending wording; PR86 exposes the complete recipe. Both shipped in 2.4.1.
The following investigation records the original alternatives and acceptance questions. Its proposal wording and unchecked historical checklist do not mean this closed feature awaits another implementation.
Historical investigation
Summary & intent
Provide a small, opt-in PSR-3 adapter for applications that need direct throwable logging without an event-dispatcher layer. This is a potential opt-in 2.x minor after the compatibility-preserving tooling/CI baseline; it does not inherently depend on the major.
Delivery gate: preserve PHP 7.4 syntax/resolution, existing container/ConfigProvider support and default discovery. The major's lifecycle guarantees are not existing 2.x behavior. See the staged roadmap.
Status: proposal; class name, message format and context policy are not approved APIs yet.
Findings & constraints
| Observed fact | Design consequence |
|---|---|
| LogErrorEventListener already provides logging through an ErrorEvent | Preserve this path for event-driven applications |
| CallableThrowableHandler can already delegate to a logger | A new class must earn its place by removing repeated standard composition |
PSR-3 reserves the exception context key for exception data |
Preserve the original throwable in that key and define merge precedence explicitly |
| The default aggregate discovers callable/PSR-14 reporters | Automatically adding a logger could duplicate diagnostics |
Alternatives & trade-offs
| Alternative | Complexity | Breaking risk | Maintenance cost | Assessment |
|---|---|---|---|---|
| Existing PSR-14 event/listener path | Existing | None | Dispatcher configuration | Appropriate when events are already required |
| Application callable only | Low | None | Repeated application policy | Valid status quo |
| Thin direct PSR-3 handler | Low | Additive when explicit | One standards-based adapter | Recommended investigation |
| Separate integration package | Medium | Additive | Extra release/distribution boundary | Justify only if the adapter grows beyond a small PSR bridge |
Proposed strategy
Evaluate Handler\LogThrowableHandler implementing ThrowableHandlerInterface, with an application-owned LoggerInterface and configurable standard log level; LogLevel::ERROR is the proposed default.
Deliver the same throwable once, preserve its identity in the PSR-3 exception context, and specify the message and caller-context precedence. Logger failures propagate through the existing reporter contract. Emit no HTTP body/stdout and install no PHP callbacks.
Keep it explicit through direct construction, autowiring or an application reporter binding. Do not add it to the default aggregate merely because a logger is available. Preserve support for psr/log 1.x, 2.x and 3.x.
Isolated investigation & validation
Use a disposable branch/worktree and a recording logger double. Compare direct logging with the existing event and callable paths using the same synthetic Throwable. Verify messages, level, context, identity, delivery count and failure propagation. No remote logger or real application data is needed.
If the adapter adds no value beyond a documented callable, retain the example instead. Before merge, discarding that isolated branch restores the baseline without consumer changes.
Guiding questions
- Should the message be the throwable message or a configurable constant/template?
- Which caller context is supported, and how is the reserved
exceptionentry protected? - Is standard-level configuration sufficient without adding severity inference?
PHP severities, arbitrary exception codes and HTTP statuses must not be conflated.
Acceptance criteria
- Decide and document naming, message, level and context precedence before freezing the API.
- Test success, original-object identity, one delivery, logger failure and no stdout across supported psr/log bounds and the retained 2.x runtime range, including the PHP 7.4 minimum.
- Verify one logger call per adapter invocation and explicit legacy integration. Do not promise the proposed major's failed-registration/no-retry guard on the unchanged 2.x handler or treat a private logger as the legacy public HTTP renderer.
- Supply complete English PHPDoc and a runnable example; update README, API/provider/cookbook/static-site docs, migration guidance where relevant, and
coisa-error-handlerskill in the same PR. - Add the appropriate Changeset and pass
composer --no-plugins check, documented-example parity and production autoload/archive checks. - Keep logger implementations, transports and callback registration application-owned.
Related independent proposals: filtering, best effort.
Activity
[-]Add a direct PSR-3 throwable reporter after the next major[/-][+]Add an opt-in direct PSR-3 throwable reporter[/+]