Clarify application error handling and reporting ownership
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
Status: initial planning. Message categories, all four output modes, uniform
|
Status: initial planning. Message categories, all four output modes, uniform
|
||||||
treatment of help and version, message prefixes, and OD-1's flag grammar and
|
treatment of help and version, message prefixes, and OD-1's flag grammar and
|
||||||
scope (including independent Progress control) are selected.
|
scope (including independent Progress control) are selected.
|
||||||
OD-2's unified reporting direction and the terminal failure model are selected.
|
OD-2's unified reporting direction, the terminal failure model, and application
|
||||||
|
ownership of error handling are selected.
|
||||||
Exact API signatures, failure explanation details, retention, and delivery
|
Exact API signatures, failure explanation details, retention, and delivery
|
||||||
mechanics remain open. Implementation has not started.
|
mechanics remain open. Implementation has not started.
|
||||||
|
|
||||||
@@ -19,6 +20,30 @@ straightforward. Design reporting conveniences around the shared output policy
|
|||||||
and invocation lifecycle. Applications continue to own their report content,
|
and invocation lifecycle. Applications continue to own their report content,
|
||||||
domain behavior, and operation outcomes.
|
domain behavior, and operation outcomes.
|
||||||
|
|
||||||
|
## CLI presentation and error-handling ownership
|
||||||
|
|
||||||
|
Applications decide how to handle errors from their operations: recover, retry,
|
||||||
|
continue silently, report a Warning, or end the invocation with a failure.
|
||||||
|
A Go `error` does not determine a CLI message category. Warnings may describe
|
||||||
|
issues with or without an underlying Go error, and handling an error does not
|
||||||
|
require emitting a message.
|
||||||
|
|
||||||
|
CommandKit handles the presentation the application requests: message category,
|
||||||
|
visibility, formatting, timing, and delivery. For terminal application failures,
|
||||||
|
the application supplies a non-zero outcome and an operator-facing explanation.
|
||||||
|
Reporting does not require the underlying Go error or undertake its tracking,
|
||||||
|
recovery, or identity preservation.
|
||||||
|
|
||||||
|
A convenience helper that explicitly presents `err.Error()` as a Warning could
|
||||||
|
fit this boundary. Such a helper would only convert the supplied error to a
|
||||||
|
message at the application's request; its inclusion and signature remain open.
|
||||||
|
|
||||||
|
CommandKit retains responsibility for handling its own errors, including
|
||||||
|
routing, parsing, and reporting failures. Integration-owned commands similarly
|
||||||
|
adapt their upstream APIs into deliberate command outcomes and presentations.
|
||||||
|
This boundary governs application error handling; ordinary Go error returns
|
||||||
|
from CommandKit APIs and writers remain available where appropriate.
|
||||||
|
|
||||||
## Current baseline
|
## Current baseline
|
||||||
|
|
||||||
[`Streams` and `Invocation`](../../identity.go) expose caller-selected output
|
[`Streams` and `Invocation`](../../identity.go) expose caller-selected output
|
||||||
@@ -49,7 +74,7 @@ Distinguish substantive application output from diagnostic message categories:
|
|||||||
- **Error:** Terminal presentation of an unrecoverable invocation failure,
|
- **Error:** Terminal presentation of an unrecoverable invocation failure,
|
||||||
resulting in a non-zero status code.
|
resulting in a non-zero status code.
|
||||||
- **Warning:** Something went wrong or deserves attention, but the invocation
|
- **Warning:** Something went wrong or deserves attention, but the invocation
|
||||||
can still succeed. A recovered problem is a warning.
|
can still succeed. The application chooses whether to report such an issue.
|
||||||
- **Info:** Informational context and useful explanation, such as which profile
|
- **Info:** Informational context and useful explanation, such as which profile
|
||||||
was selected or a final operation summary.
|
was selected or a final operation summary.
|
||||||
- **Progress:** Streaming updates about work underway, such as items processed.
|
- **Progress:** Streaming updates about work underway, such as items processed.
|
||||||
@@ -77,9 +102,8 @@ Applications and integrations are not required to generate messages in any
|
|||||||
category. Enabling a category adds no output when there are no messages in it;
|
category. Enabling a category adds no output when there are no messages in it;
|
||||||
other output remains subject to its own visibility rules.
|
other output remains subject to its own visibility rules.
|
||||||
|
|
||||||
Error presentation follows the terminal failure model below. Problems from
|
Error presentation follows the terminal failure model below. An application
|
||||||
which the invocation recovers are warnings, even when an attempted operation
|
may report a recovered problem as a Warning or continue without a message.
|
||||||
failed internally.
|
|
||||||
|
|
||||||
Apply the same policy to help and version. There are no command-specific
|
Apply the same policy to help and version. There are no command-specific
|
||||||
exceptions for successful output:
|
exceptions for successful output:
|
||||||
@@ -120,15 +144,12 @@ The same boundary applies to core routing and parsing failures that prevent
|
|||||||
handler execution. The application entry point retains ownership of process
|
handler execution. The application entry point retains ownership of process
|
||||||
exit; CommandKit ends the invocation and returns its outcome.
|
exit; CommandKit ends the invocation and returns its outcome.
|
||||||
|
|
||||||
For example, a handler returns immediately on an unrecoverable failure:
|
For example, if an export operation fails and the application decides it cannot
|
||||||
|
continue, the handler returns a non-zero outcome with an explicit explanation
|
||||||
```go
|
such as "Unable to export the requested report." The application can choose to
|
||||||
result, err := performOperation()
|
include detail from a Go error in that explanation. CommandKit presents the
|
||||||
if err != nil {
|
supplied explanation without automatically deriving text from an application
|
||||||
return commandkit.Failure(err)
|
error. The exact failure-construction API remains open under OD-3.
|
||||||
}
|
|
||||||
// Continue normal reporting only after successful operation.
|
|
||||||
```
|
|
||||||
|
|
||||||
Output streamed before the failure remains visible according to its selected
|
Output streamed before the failure remains visible according to its selected
|
||||||
mode; terminal failure does not withdraw earlier bytes. Deferred messages,
|
mode; terminal failure does not withdraw earlier bytes. Deferred messages,
|
||||||
@@ -295,9 +316,9 @@ output is not part of the proposed direction.
|
|||||||
|
|
||||||
Keep errors understandable in every mode, including source locations and
|
Keep errors understandable in every mode, including source locations and
|
||||||
related explanatory context. Unrelated warnings and informational messages
|
related explanatory context. Unrelated warnings and informational messages
|
||||||
remain subject to the selected mode. Retain suppressed diagnostics for
|
remain subject to the selected mode. Whether to retain submitted messages for
|
||||||
programmatic inspection rather than equating suppression with loss of evidence.
|
programmatic inspection, including suppressed messages, remains open under
|
||||||
The exact representation of retained and delivered diagnostics remains open.
|
OD-3. This concerns presentation records, not application error tracking.
|
||||||
|
|
||||||
## Selected consumer reporting API direction
|
## Selected consumer reporting API direction
|
||||||
|
|
||||||
@@ -332,7 +353,8 @@ application domain classification. CommandKit presents a failed outcome through
|
|||||||
the same reporting facility as the terminal step. Error explanations belong to
|
the same reporting facility as the terminal step. Error explanations belong to
|
||||||
that returned failure, including rich upstream explanations. Typed diagnostic
|
that returned failure, including rich upstream explanations. Typed diagnostic
|
||||||
submission must preserve this relationship instead of permitting independently
|
submission must preserve this relationship instead of permitting independently
|
||||||
emitted Error messages during normal execution.
|
emitted Error messages during normal execution. Application failures carry
|
||||||
|
explicit status and presentation content; they do not require a Go error cause.
|
||||||
|
|
||||||
Use the reporter as the common diagnostic submission path, replacing the earlier
|
Use the reporter as the common diagnostic submission path, replacing the earlier
|
||||||
proposal to split submission between a reporter and `Outcome.Diagnostics`.
|
proposal to split submission between a reporter and `Outcome.Diagnostics`.
|
||||||
@@ -354,9 +376,12 @@ those capabilities through the shared CommandKit presentation policy.
|
|||||||
|
|
||||||
Support consistent reporting of ConfigKit errors and warnings as its adopted
|
Support consistent reporting of ConfigKit errors and warnings as its adopted
|
||||||
public API evolves. This roadmap does not assume that a future warning API
|
public API evolves. This roadmap does not assume that a future warning API
|
||||||
already exists or prescribe its upstream shape. Preserve useful native
|
already exists or prescribe its upstream shape. Integration-owned commands
|
||||||
diagnostic detail and supported error identity, and coordinate returned errors
|
select the outcome and submit useful native diagnostic detail for presentation.
|
||||||
with diagnostics that already explain them.
|
Core presents those records under the shared policy; it does not infer an
|
||||||
|
application's recovery decisions or classify arbitrary Go errors. Applications
|
||||||
|
using upstream libraries directly retain the same choice over outcomes and
|
||||||
|
messages as for their other operations.
|
||||||
|
|
||||||
Debug output follows the same upstream disclosure and safe-rendering contracts.
|
Debug output follows the same upstream disclosure and safe-rendering contracts.
|
||||||
Enabling debug does not authorize secret disclosure or bypass owning-library
|
Enabling debug does not authorize secret disclosure or bypass owning-library
|
||||||
@@ -368,6 +393,8 @@ rules.
|
|||||||
immediate and deferred diagnostics, failure after partial output, help and
|
immediate and deferred diagnostics, failure after partial output, help and
|
||||||
version, and integration diagnostics in every mode. Include applications that
|
version, and integration diagnostics in every mode. Include applications that
|
||||||
emit no Progress messages and the distinction between Info and Progress.
|
emit no Progress messages and the distinction between Info and Progress.
|
||||||
|
Cover silent recovery, an explicit Warning with or without a Go error, and a
|
||||||
|
terminal failure with an explicit explanation and no Go error cause.
|
||||||
2. Review current diagnostic batching, parsing, help, outcome presentation, and
|
2. Review current diagnostic batching, parsing, help, outcome presentation, and
|
||||||
writer ownership to identify the smallest shared changes. Include invocation
|
writer ownership to identify the smallest shared changes. Include invocation
|
||||||
failures that occur before a handler receives its `Invocation`.
|
failures that occur before a handler receives its `Invocation`.
|
||||||
@@ -388,23 +415,33 @@ rules.
|
|||||||
reporting after terminal error presentation, including deferred and late
|
reporting after terminal error presentation, including deferred and late
|
||||||
writes under the selected OD-4 behavior.
|
writes under the selected OD-4 behavior.
|
||||||
6. Update GoDoc, the CLI reference, consumer guidance, and release documentation
|
6. Update GoDoc, the CLI reference, consumer guidance, and release documentation
|
||||||
when implemented. Review whether any resulting architectural change needs an
|
when implemented. Reconcile the selected error-handling boundary with
|
||||||
ADR; exact reporting APIs and flag syntax remain API/CLI contracts.
|
ADR 0005's existing outcome and error-identity commitments before changing
|
||||||
|
those contracts. Record any resulting architectural change in a new ADR;
|
||||||
|
exact reporting APIs and flag syntax remain API/CLI contracts.
|
||||||
|
|
||||||
## Open Decisions
|
## Open Decisions
|
||||||
|
|
||||||
### OD-3: Failure presentation and diagnostic retention
|
### OD-3: Failure presentation and diagnostic retention
|
||||||
|
|
||||||
The terminal failure model is selected above. How are detailed explanations
|
The terminal failure model and application error-handling boundary are selected
|
||||||
attached to the returned failure, including application domain failures? How
|
above. The remaining questions concern explicit presentation content:
|
||||||
are recovered upstream problems represented as warnings while preserving their
|
|
||||||
native context? Which contextual records belong to a terminal error explanation?
|
- How does a handler supply a non-zero outcome with a simple explanation or
|
||||||
How are mixed upstream
|
multiple structured explanatory records, including application domain failures?
|
||||||
diagnostic batches filtered while preserving useful native rendering? What is
|
- How do callers and integration adapters identify the context belonging to a
|
||||||
retained when presentation is suppressed, and how is duplicate presentation
|
terminal explanation, and present mixed diagnostic batches while preserving
|
||||||
prevented without hiding unrelated failures?
|
useful native rendering and applying visibility to independent messages?
|
||||||
How do adapters apply the selected prefixes to mixed or already-labelled native
|
- Which submitted messages, if any, are retained for programmatic inspection,
|
||||||
diagnostics? What presentation should streaming Progress use?
|
including when suppressed? How is that observation exposed separately from
|
||||||
|
message submission?
|
||||||
|
- How is duplicate presentation avoided, and how do adapters apply prefixes to
|
||||||
|
mixed or already-labelled native diagnostics?
|
||||||
|
- What presentation should streaming Progress use? Is a convenience helper for
|
||||||
|
explicitly presenting `err.Error()` as a Warning useful enough to include?
|
||||||
|
|
||||||
|
Application error classification, recovery, and cause tracking are outside
|
||||||
|
these questions. Delivery failures produced by reporting remain under OD-4.
|
||||||
|
|
||||||
### OD-4: Delivery lifecycle and quiet execution
|
### OD-4: Delivery lifecycle and quiet execution
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user