shinway / internal /errors /errors_test.go
sshinmen's picture
Configure for HF Spaces: port 7860, cloud deploy mode, PORT env support
5e6ff88
Raw
History Blame Contribute Delete
3.8 kB
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")
}
}