Classify recovery setup failures by their actual cause

This commit is contained in:
2026-11-03 00:15:36 +00:00
parent dfaa652098
commit 2a7bed87db
7 changed files with 144 additions and 24 deletions

View File

@@ -108,28 +108,18 @@ func observe(ctx context.Context, evidence Evidence) (Observation, error) {
}
valid, err := git.ValidateTagRef(ctx, evidence.RepositoryDir, evidence.Tag)
if err != nil {
return Observation{Evidence: evidence, State: Unknown}, recoveryFailure(ctx, "remote_observation", err)
return Observation{Evidence: evidence, State: Unknown}, observationFailure(ctx, err)
}
if !valid {
return Observation{Evidence: evidence, State: Unknown}, &RecoveryError{Kind: "invalid_evidence"}
}
endpoint, err := git.ObserveEndpoint(ctx, evidence.RepositoryDir, evidence.Endpoint, evidence.Remote)
if err != nil {
if ctx.Err() != nil {
return Observation{Evidence: evidence, State: Unknown}, &RecoveryError{Kind: "canceled", cause: ctx.Err()}
}
kind := "endpoint_changed"
if errors.Is(err, git.ErrEndpointChanged) {
return Observation{Evidence: evidence, State: Unknown}, &RecoveryError{Kind: kind, cause: err}
}
if evidence.Remote != "" {
kind = "transport_configuration"
}
return Observation{Evidence: evidence, State: Unknown}, &RecoveryError{Kind: kind, cause: err}
return Observation{Evidence: evidence, State: Unknown}, observationFailure(ctx, err)
}
ref, err := endpoint.QueryTag(ctx, evidence.RepositoryDir, evidence.Tag)
if err != nil {
return Observation{Evidence: evidence, State: Unknown}, recoveryFailure(ctx, "remote_observation", err)
return Observation{Evidence: evidence, State: Unknown}, observationFailure(ctx, err)
}
result, err := classify(evidence, ref)
if err != nil && ctx.Err() != nil {
@@ -138,6 +128,17 @@ func observe(ctx context.Context, evidence Evidence) (Observation, error) {
return result, err
}
func observationFailure(ctx context.Context, err error) *RecoveryError {
kind := "remote_observation"
switch {
case errors.Is(err, git.ErrEndpointChanged):
kind = "endpoint_changed"
case errors.Is(err, git.ErrTransportConfiguration):
kind = "transport_configuration"
}
return recoveryFailure(ctx, kind, err)
}
// Reconcile observes the recorded endpoint and classifies its exact tag.
func Reconcile(ctx context.Context, evidence Evidence) (Observation, error) {
return observe(ctx, evidence)