Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
83 lines
2.9 KiB
Go
83 lines
2.9 KiB
Go
package agenthost
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestProviderErrorPreservesStructuredDiagnosticsAndCause(t *testing.T) {
|
|
cause := errors.New("provider process rejected the request")
|
|
providerErr := &ProviderError{
|
|
Code: "provider_auth_required",
|
|
Message: "Agent provider needs authentication",
|
|
DebugMessage: "provider exited with status 1",
|
|
Cause: cause,
|
|
}
|
|
wrapped := fmt.Errorf("create agent session: %w", providerErr)
|
|
|
|
var got *ProviderError
|
|
if !errors.As(wrapped, &got) {
|
|
t.Fatalf("errors.As(%v) did not preserve ProviderError", wrapped)
|
|
}
|
|
if got.Code != providerErr.Code || got.Message != providerErr.Message || got.DebugMessage != providerErr.DebugMessage {
|
|
t.Fatalf("ProviderError = %#v, want %#v", got, providerErr)
|
|
}
|
|
if !errors.Is(wrapped, cause) {
|
|
t.Fatalf("errors.Is(%v, cause) = false", wrapped)
|
|
}
|
|
}
|
|
|
|
func TestProviderErrorFallsBackWithoutInventingAStableCode(t *testing.T) {
|
|
cause := errors.New("provider unavailable")
|
|
providerErr := &ProviderError{Cause: cause}
|
|
if got := providerErr.Error(); got != cause.Error() {
|
|
t.Fatalf("Error() = %q, want %q", got, cause.Error())
|
|
}
|
|
if providerErr.Code != "" {
|
|
t.Fatalf("Code = %q, want no invented provider taxonomy", providerErr.Code)
|
|
}
|
|
}
|
|
|
|
func TestNewProviderErrorLeavesDeliveryUnknownContextErrorsRecoverable(t *testing.T) {
|
|
for _, cause := range []error{
|
|
fmt.Errorf("provider start: %w", context.Canceled),
|
|
fmt.Errorf("provider start: %w", context.DeadlineExceeded),
|
|
} {
|
|
mapped := NewProviderError("request_failed", "Provider request failed", "timeout", cause)
|
|
var providerErr *ProviderError
|
|
if errors.As(mapped, &providerErr) {
|
|
t.Fatalf("NewProviderError(%v) = %#v, want unclassified context error", cause, providerErr)
|
|
}
|
|
if !errors.Is(mapped, cause) {
|
|
t.Fatalf("NewProviderError(%v) did not preserve original error", cause)
|
|
}
|
|
}
|
|
if mapped := NewProviderError("request_failed", "Provider request failed", "", nil); mapped != nil {
|
|
t.Fatalf("NewProviderError(nil) = %v, want nil", mapped)
|
|
}
|
|
}
|
|
|
|
func TestNewProviderStartTimeoutErrorPreservesTypedVerdictAndDeadlineCause(t *testing.T) {
|
|
cause := fmt.Errorf("provider start: %w", context.DeadlineExceeded)
|
|
mapped := NewProviderStartTimeoutError(
|
|
"Agent provider took too long to start",
|
|
"provider startup exceeded its deadline",
|
|
cause,
|
|
)
|
|
var providerErr *ProviderError
|
|
if !errors.As(mapped, &providerErr) {
|
|
t.Fatalf("NewProviderStartTimeoutError() = %v, want ProviderError", mapped)
|
|
}
|
|
if providerErr.Code != ProviderErrorCodeStartTimeout {
|
|
t.Fatalf("ProviderError code = %q, want %q", providerErr.Code, ProviderErrorCodeStartTimeout)
|
|
}
|
|
if !errors.Is(mapped, context.DeadlineExceeded) {
|
|
t.Fatalf("mapped error = %v, want deadline cause preserved", mapped)
|
|
}
|
|
if mapped := NewProviderStartTimeoutError("", "", nil); mapped != nil {
|
|
t.Fatalf("NewProviderStartTimeoutError(nil) = %v, want nil", mapped)
|
|
}
|
|
}
|