github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/requestconfig/requestconfig_test.go (about) 1 package requestconfig 2 3 import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "net/url" 8 "testing" 9 10 "github.com/anthropics/anthropic-sdk-go/internal/apierror" 11 "github.com/anthropics/anthropic-sdk-go/shared" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 // mockBaseURL is a helper function to create a URL for testing 17 func mockBaseURL(server *httptest.Server) *url.URL { 18 u, _ := url.Parse(server.URL) 19 return u 20 } 21 22 // TestErrorWithRequestID tests that RequestID is properly extracted from response headers 23 // and included in the Error struct when API errors occur 24 func TestErrorWithRequestID(t *testing.T) { 25 // Create a test server that simulates an API returning an error with request-id 26 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 27 // Set the request-id header - using the same header name as in the code 28 w.Header().Set("request-id", "req_123456789") 29 w.Header().Set("anthropic-workspace-id", "wrkspc_123") 30 // Return a 400 error with error JSON 31 w.WriteHeader(http.StatusBadRequest) 32 w.Write([]byte(`{"error":{"type":"invalid_request_error","message":"Invalid request"}}`)) 33 })) 34 defer server.Close() 35 36 // Create a request to the test server 37 req, err := http.NewRequest("GET", "/test", nil) 38 require.NoError(t, err, "Failed to create request") 39 40 // Create a RequestConfig with proper BaseURL 41 cfg := &RequestConfig{ 42 Context: context.Background(), 43 Request: req, 44 BaseURL: mockBaseURL(server), 45 HTTPClient: http.DefaultClient, 46 } 47 48 // Execute the request, which should return an error 49 err = cfg.Execute() 50 require.Error(t, err, "Expected an error, but got nil") 51 52 // The error should be of type *apierror.Error 53 apiErr, ok := err.(*apierror.Error) 54 require.True(t, ok, "Expected error of type *apierror.Error, got %T", err) 55 56 // Verify that RequestID field was properly set from the header 57 expectedRequestID := "req_123456789" 58 assert.Equal(t, expectedRequestID, apiErr.RequestID, "Expected RequestID to be %s, got %s", expectedRequestID, apiErr.RequestID) 59 assert.Equal(t, "wrkspc_123", apiErr.WorkspaceID) 60 61 // Verify that the error message includes the RequestID 62 errorMsg := apiErr.Error() 63 assert.Contains(t, errorMsg, "Request-ID: req_123456789", "Error message should contain request ID") 64 assert.Contains(t, errorMsg, "Workspace-ID: wrkspc_123", "Error message should contain workspace ID") 65 } 66 67 func TestErrorType(t *testing.T) { 68 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 69 w.Header().Set("request-id", "req_test123") 70 w.WriteHeader(http.StatusBadRequest) 71 w.Write([]byte(`{"type":"error","error":{"type":"invalid_request_error","message":"Bad request"}}`)) 72 })) 73 defer server.Close() 74 75 req, err := http.NewRequest("GET", "/test", nil) 76 require.NoError(t, err) 77 78 cfg := &RequestConfig{ 79 Context: context.Background(), 80 Request: req, 81 BaseURL: mockBaseURL(server), 82 HTTPClient: http.DefaultClient, 83 } 84 err = cfg.Execute() 85 require.Error(t, err) 86 87 apiErr, ok := err.(*apierror.Error) 88 require.True(t, ok, "Expected *apierror.Error, got %T", err) 89 assert.Equal(t, shared.ErrorTypeInvalidRequestError, apiErr.Type()) 90 assert.Equal(t, 400, apiErr.StatusCode) 91 assert.Equal(t, "req_test123", apiErr.RequestID) 92 } 93 94 func TestErrorTypeAbsent(t *testing.T) { 95 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 96 w.WriteHeader(http.StatusInternalServerError) 97 w.Write([]byte(`{"message":"Internal error"}`)) 98 })) 99 defer server.Close() 100 101 req, err := http.NewRequest("GET", "/test", nil) 102 require.NoError(t, err) 103 104 cfg := &RequestConfig{ 105 Context: context.Background(), 106 Request: req, 107 BaseURL: mockBaseURL(server), 108 HTTPClient: http.DefaultClient, 109 } 110 err = cfg.Execute() 111 require.Error(t, err) 112 113 apiErr, ok := err.(*apierror.Error) 114 require.True(t, ok, "Expected *apierror.Error, got %T", err) 115 assert.Equal(t, shared.ErrorType(""), apiErr.Type()) 116 assert.Equal(t, 500, apiErr.StatusCode) 117 }