| package errors |
|
|
| import ( |
| "errors" |
| "testing" |
| ) |
|
|
| func TestNew(t *testing.T) { |
| e := New(CategoryInternal, "something went wrong") |
|
|
| if e.Category != CategoryInternal { |
| t.Errorf("Expected category Internal, got %v", e.Category) |
| } |
| if e.Message != "something went wrong" { |
| t.Errorf("Expected message 'something went wrong', got '%s'", e.Message) |
| } |
| if e.StatusCode != 500 { |
| t.Errorf("Expected status code 500, got %d", e.StatusCode) |
| } |
| if e.Retryable { |
| t.Error("Internal errors should not be retryable by default") |
| } |
| } |
|
|
| func TestNewWithCause(t *testing.T) { |
| cause := errors.New("underlying error") |
| e := NewWithCause(CategoryUpstream, "upstream failed", cause) |
|
|
| if e.Cause != cause { |
| t.Error("Cause not set correctly") |
| } |
|
|
| expectedMsg := "[upstream] upstream failed: underlying error" |
| if e.Error() != expectedMsg { |
| t.Errorf("Expected error message '%s', got '%s'", expectedMsg, e.Error()) |
| } |
| } |
|
|
| func TestWrap(t *testing.T) { |
| original := errors.New("original error") |
| wrapped := Wrap(original, CategoryNetwork, "network issue") |
|
|
| if wrapped == nil { |
| t.Fatal("Wrap returned nil for non-nil error") |
| } |
|
|
| if wrapped.Cause != original { |
| t.Error("Wrapped error should preserve original cause") |
| } |
|
|
| pe := New(CategoryRateLimit, "rate limited") |
| wrapped2 := Wrap(pe, CategoryUnknown, "wrapped") |
|
|
| if wrapped2 != pe { |
| t.Error("Wrapping PipelineError should return the same error") |
| } |
| } |
|
|
| func TestWrapNil(t *testing.T) { |
| wrapped := Wrap(nil, CategoryInternal, "test") |
| if wrapped != nil { |
| t.Error("Wrapping nil should return nil") |
| } |
| } |
|
|
| func TestErrorHelpers(t *testing.T) { |
| tests := []struct { |
| name string |
| err *PipelineError |
| expectedCat ErrorCategory |
| expectedStatus int |
| expectedRetry bool |
| }{ |
| {"Auth", AuthError("unauthorized"), CategoryAuth, 401, false}, |
| {"RateLimit", RateLimitError("too many requests"), CategoryRateLimit, 429, true}, |
| {"Validation", ValidationError("invalid input"), CategoryValidation, 400, false}, |
| {"Upstream", UpstreamError("provider down"), CategoryUpstream, 502, true}, |
| {"Internal", InternalError("server error"), CategoryInternal, 500, false}, |
| {"Network", NetworkError("connection lost"), CategoryNetwork, 503, true}, |
| {"Timeout", TimeoutError("request timeout"), CategoryTimeout, 504, true}, |
| } |
|
|
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| if tt.err.Category != tt.expectedCat { |
| t.Errorf("Expected category %v, got %v", tt.expectedCat, tt.err.Category) |
| } |
| if tt.err.StatusCode != tt.expectedStatus { |
| t.Errorf("Expected status %d, got %d", tt.expectedStatus, tt.err.StatusCode) |
| } |
| if tt.err.Retryable != tt.expectedRetry { |
| t.Errorf("Expected retryable=%v, got %v", tt.expectedRetry, tt.err.Retryable) |
| } |
| }) |
| } |
| } |
|
|
| func TestWithContext(t *testing.T) { |
| e := New(CategoryValidation, "invalid field"). |
| WithContext("field", "email"). |
| WithContext("value", "invalid-email") |
|
|
| if e.Context == nil { |
| t.Fatal("Context should not be nil") |
| } |
|
|
| if e.Context["field"] != "email" { |
| t.Errorf("Expected field='email', got %v", e.Context["field"]) |
| } |
| } |
|
|
| func TestIsPipelineError(t *testing.T) { |
| pe := New(CategoryInternal, "test") |
| result, ok := IsPipelineError(pe) |
| if !ok { |
| t.Error("IsPipelineError should return true for PipelineError") |
| } |
| if result != pe { |
| t.Error("IsPipelineError should return the same error") |
| } |
|
|
| stdErr := errors.New("standard error") |
| _, ok = IsPipelineError(stdErr) |
| if ok { |
| t.Error("IsPipelineError should return false for standard error") |
| } |
| } |
|
|
| func TestIsRetryableError(t *testing.T) { |
| rateLimit := RateLimitError("test") |
| if !IsRetryableError(rateLimit) { |
| t.Error("Rate limit error should be retryable") |
| } |
|
|
| auth := AuthError("test") |
| if IsRetryableError(auth) { |
| t.Error("Auth error should not be retryable") |
| } |
| } |
|
|