package structuredoutput import ( "errors" "testing" "gitea.maximumdirect.net/eric/audita/v3/internal/framework/outcomes" ) func TestFailureClassificationKeepsCauseAndSafeMessage(t *testing.T) { cause := errors.New("provider token secret-value") malformed := &Failure{Kind: FailureMalformedOutput, Message: "malformed structured output", Cause: cause} if !IsMalformedError(malformed) || !errors.Is(malformed, cause) || malformed.Error() != "malformed structured output" { t.Fatalf("malformed classification: %v", malformed) } runtime := &Failure{Kind: FailureRuntime, Message: "structured model call failed", Cause: cause} if IsMalformedError(runtime) || IsMalformedError(cause) || IsMalformedError(nil) || !errors.Is(runtime, cause) || runtime.Error() != "structured model call failed" { t.Fatalf("runtime classification: %v", runtime) } } func TestRecoverableFailureKeepsTypedCauseOutOfSafeMessage(t *testing.T) { cause := errors.New("provider response contained a secret") failure := &Failure{ Class: FailureRecoverable, Reason: outcomes.ReasonTransportFailed, Message: "model transport failed", Cause: cause, } wrapped := errors.Join(errors.New("operation failed"), failure) if !IsRecoverable(wrapped) || !errors.Is(wrapped, cause) { t.Fatalf("recoverable failure lost classification or cause: %v", wrapped) } if failure.Error() != "model transport failed" { t.Fatalf("unsafe failure text: %q", failure.Error()) } for _, class := range []FailureClass{FailureFatal, FailureCanceled} { if IsRecoverable(&Failure{Class: class, Cause: cause}) { t.Fatalf("%s classified as recoverable", class) } } if IsRecoverable(cause) { t.Fatal("bare internal error classified as recoverable") } }