|
1 | | -import { sanitizeErrorMessage } from "../validation-helpers" |
| 1 | +import { sanitizeErrorMessage, handleValidationError } from "../validation-helpers" |
| 2 | + |
| 3 | +vi.mock("../../../../i18n", () => ({ |
| 4 | + t: (key: string) => { |
| 5 | + // Return the key itself for testing purposes |
| 6 | + const translations: Record<string, string> = { |
| 7 | + "common:errors.api.invalidKeyInvalidChars": "API key contains invalid characters.", |
| 8 | + "embeddings:validation.connectionFailed": "Connection failed", |
| 9 | + "embeddings:validation.invalidResponse": "Invalid response", |
| 10 | + "embeddings:validation.configurationError": "Configuration error", |
| 11 | + "embeddings:validation.authenticationFailed": "Authentication failed", |
| 12 | + "embeddings:validation.modelNotAvailable": "Model not available", |
| 13 | + "embeddings:validation.invalidEndpoint": "Invalid endpoint", |
| 14 | + "embeddings:validation.serviceUnavailable": "Service unavailable", |
| 15 | + } |
| 16 | + return translations[key] || key |
| 17 | + }, |
| 18 | +})) |
2 | 19 |
|
3 | 20 | describe("sanitizeErrorMessage", () => { |
4 | 21 | it("should sanitize Unix-style file paths", () => { |
@@ -90,3 +107,106 @@ describe("sanitizeErrorMessage", () => { |
90 | 107 | expect(sanitizeErrorMessage(input)).toBe(expected) |
91 | 108 | }) |
92 | 109 | }) |
| 110 | + |
| 111 | +describe("handleValidationError", () => { |
| 112 | + it("should handle ByteString conversion error with user-friendly message", () => { |
| 113 | + const error = new Error( |
| 114 | + "Cannot convert argument to a ByteString because the character at index 8 has a value of 1040 which is greater than 255", |
| 115 | + ) |
| 116 | + const result = handleValidationError(error, "openai-compatible") |
| 117 | + expect(result.valid).toBe(false) |
| 118 | + expect(result.error).toBe("API key contains invalid characters.") |
| 119 | + }) |
| 120 | + |
| 121 | + it("should handle ByteString error with various character indices", () => { |
| 122 | + const error = new Error( |
| 123 | + "Cannot convert argument to a ByteString because the character at index 0 has a value of 256", |
| 124 | + ) |
| 125 | + const result = handleValidationError(error, "openai") |
| 126 | + expect(result.valid).toBe(false) |
| 127 | + expect(result.error).toBe("API key contains invalid characters.") |
| 128 | + }) |
| 129 | + |
| 130 | + it("should handle connection refused errors", () => { |
| 131 | + const error = new Error("ECONNREFUSED 127.0.0.1:11434") |
| 132 | + const result = handleValidationError(error, "ollama") |
| 133 | + expect(result.valid).toBe(false) |
| 134 | + expect(result.error).toBe("Connection failed") |
| 135 | + }) |
| 136 | + |
| 137 | + it("should handle ENOTFOUND errors", () => { |
| 138 | + const error = new Error("getaddrinfo ENOTFOUND api.example.com") |
| 139 | + const result = handleValidationError(error, "openai") |
| 140 | + expect(result.valid).toBe(false) |
| 141 | + expect(result.error).toBe("Connection failed") |
| 142 | + }) |
| 143 | + |
| 144 | + it("should handle timeout errors", () => { |
| 145 | + const error = new Error("ETIMEDOUT") |
| 146 | + const result = handleValidationError(error, "openai") |
| 147 | + expect(result.valid).toBe(false) |
| 148 | + expect(result.error).toBe("Connection failed") |
| 149 | + }) |
| 150 | + |
| 151 | + it("should handle invalid JSON response errors", () => { |
| 152 | + const error = new Error("Failed to parse response JSON") |
| 153 | + const result = handleValidationError(error, "openai") |
| 154 | + expect(result.valid).toBe(false) |
| 155 | + expect(result.error).toBe("Invalid response") |
| 156 | + }) |
| 157 | + |
| 158 | + it("should preserve generic error messages", () => { |
| 159 | + const error = new Error("Something went wrong") |
| 160 | + const result = handleValidationError(error, "openai") |
| 161 | + expect(result.valid).toBe(false) |
| 162 | + expect(result.error).toBe("Something went wrong") |
| 163 | + }) |
| 164 | + |
| 165 | + it("should handle errors with status codes", () => { |
| 166 | + const error = { status: 401, message: "Unauthorized" } |
| 167 | + const result = handleValidationError(error, "openai") |
| 168 | + expect(result.valid).toBe(false) |
| 169 | + expect(result.error).toBe("Authentication failed") |
| 170 | + }) |
| 171 | + |
| 172 | + it("should handle 404 errors for openai provider", () => { |
| 173 | + const error = { status: 404, message: "Not Found" } |
| 174 | + const result = handleValidationError(error, "openai") |
| 175 | + expect(result.valid).toBe(false) |
| 176 | + expect(result.error).toBe("Model not available") |
| 177 | + }) |
| 178 | + |
| 179 | + it("should handle 404 errors for non-openai providers", () => { |
| 180 | + const error = { status: 404, message: "Not Found" } |
| 181 | + const result = handleValidationError(error, "ollama") |
| 182 | + expect(result.valid).toBe(false) |
| 183 | + expect(result.error).toBe("Invalid endpoint") |
| 184 | + }) |
| 185 | + |
| 186 | + it("should handle rate limit errors", () => { |
| 187 | + const error = { status: 429, message: "Too Many Requests" } |
| 188 | + const result = handleValidationError(error, "openai") |
| 189 | + expect(result.valid).toBe(false) |
| 190 | + expect(result.error).toBe("Service unavailable") |
| 191 | + }) |
| 192 | + |
| 193 | + it("should allow custom handlers to override standard handling", () => { |
| 194 | + const error = new Error("Custom error") |
| 195 | + const customHandlers = { |
| 196 | + beforeStandardHandling: () => ({ valid: false, error: "Custom handled error" }), |
| 197 | + } |
| 198 | + const result = handleValidationError(error, "openai", customHandlers) |
| 199 | + expect(result.valid).toBe(false) |
| 200 | + expect(result.error).toBe("Custom handled error") |
| 201 | + }) |
| 202 | + |
| 203 | + it("should continue with standard handling if custom handler returns undefined", () => { |
| 204 | + const error = new Error("ECONNREFUSED") |
| 205 | + const customHandlers = { |
| 206 | + beforeStandardHandling: () => undefined, |
| 207 | + } |
| 208 | + const result = handleValidationError(error, "openai", customHandlers) |
| 209 | + expect(result.valid).toBe(false) |
| 210 | + expect(result.error).toBe("Connection failed") |
| 211 | + }) |
| 212 | +}) |
0 commit comments