ai.matey.http.core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/cjs/auth.js +173 -0
- package/dist/cjs/auth.js.map +1 -0
- package/dist/cjs/cors.js +140 -0
- package/dist/cjs/cors.js.map +1 -0
- package/dist/cjs/error-handler.js +147 -0
- package/dist/cjs/error-handler.js.map +1 -0
- package/dist/cjs/handler.js +335 -0
- package/dist/cjs/handler.js.map +1 -0
- package/dist/cjs/health.js +218 -0
- package/dist/cjs/health.js.map +1 -0
- package/dist/cjs/index.js +83 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/rate-limiter.js +163 -0
- package/dist/cjs/rate-limiter.js.map +1 -0
- package/dist/cjs/request-parser.js +141 -0
- package/dist/cjs/request-parser.js.map +1 -0
- package/dist/cjs/response-formatter.js +218 -0
- package/dist/cjs/response-formatter.js.map +1 -0
- package/dist/cjs/route-matcher.js +178 -0
- package/dist/cjs/route-matcher.js.map +1 -0
- package/dist/cjs/streaming-handler.js +120 -0
- package/dist/cjs/streaming-handler.js.map +1 -0
- package/dist/cjs/types.js +11 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/auth.js +163 -0
- package/dist/esm/auth.js.map +1 -0
- package/dist/esm/cors.js +134 -0
- package/dist/esm/cors.js.map +1 -0
- package/dist/esm/error-handler.js +137 -0
- package/dist/esm/error-handler.js.map +1 -0
- package/dist/esm/handler.js +331 -0
- package/dist/esm/handler.js.map +1 -0
- package/dist/esm/health.js +210 -0
- package/dist/esm/health.js.map +1 -0
- package/dist/esm/index.js +30 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/rate-limiter.js +156 -0
- package/dist/esm/rate-limiter.js.map +1 -0
- package/dist/esm/request-parser.js +136 -0
- package/dist/esm/request-parser.js.map +1 -0
- package/dist/esm/response-formatter.js +206 -0
- package/dist/esm/response-formatter.js.map +1 -0
- package/dist/esm/route-matcher.js +171 -0
- package/dist/esm/route-matcher.js.map +1 -0
- package/dist/esm/streaming-handler.js +112 -0
- package/dist/esm/streaming-handler.js.map +1 -0
- package/dist/esm/types.js +10 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/auth.d.ts +37 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/cors.d.ts +26 -0
- package/dist/types/cors.d.ts.map +1 -0
- package/dist/types/error-handler.d.ts +38 -0
- package/dist/types/error-handler.d.ts.map +1 -0
- package/dist/types/handler.d.ts +45 -0
- package/dist/types/handler.d.ts.map +1 -0
- package/dist/types/health.d.ts +164 -0
- package/dist/types/health.d.ts.map +1 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/rate-limiter.d.ts +56 -0
- package/dist/types/rate-limiter.d.ts.map +1 -0
- package/dist/types/request-parser.d.ts +22 -0
- package/dist/types/request-parser.d.ts.map +1 -0
- package/dist/types/response-formatter.d.ts +49 -0
- package/dist/types/response-formatter.d.ts.map +1 -0
- package/dist/types/route-matcher.d.ts +45 -0
- package/dist/types/route-matcher.d.ts.map +1 -0
- package/dist/types/streaming-handler.d.ts +40 -0
- package/dist/types/streaming-handler.d.ts.map +1 -0
- package/dist/types/types.d.ts +398 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +73 -0
- package/readme.md +60 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles errors in HTTP requests and formats appropriate responses.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { sendError, detectProviderFormat } from './response-formatter.js';
|
|
9
|
+
import { AdapterError, ValidationError, AuthenticationError, RateLimitError, NetworkError, ProviderError, StreamError, } from 'ai.matey.errors';
|
|
10
|
+
/**
|
|
11
|
+
* Default error handler
|
|
12
|
+
*/
|
|
13
|
+
export const defaultErrorHandler = (error, req, res) => {
|
|
14
|
+
// Detect provider format from request
|
|
15
|
+
const format = detectProviderFormat(req.url || '');
|
|
16
|
+
// Map error to HTTP status code
|
|
17
|
+
const statusCode = getHTTPStatusCode(error);
|
|
18
|
+
// Log error (in production, this should go to a proper logger)
|
|
19
|
+
if (statusCode >= 500) {
|
|
20
|
+
console.error('HTTP Server Error:', error);
|
|
21
|
+
}
|
|
22
|
+
// Send error response
|
|
23
|
+
sendError(res, error, statusCode, format);
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Get HTTP status code from error
|
|
28
|
+
*/
|
|
29
|
+
function getHTTPStatusCode(error) {
|
|
30
|
+
// Check for adapter errors
|
|
31
|
+
if (error instanceof ValidationError) {
|
|
32
|
+
return 400;
|
|
33
|
+
}
|
|
34
|
+
if (error instanceof AuthenticationError) {
|
|
35
|
+
return 401;
|
|
36
|
+
}
|
|
37
|
+
if (error instanceof RateLimitError) {
|
|
38
|
+
return 429;
|
|
39
|
+
}
|
|
40
|
+
if (error instanceof NetworkError) {
|
|
41
|
+
return 502;
|
|
42
|
+
}
|
|
43
|
+
if (error instanceof ProviderError) {
|
|
44
|
+
return 503;
|
|
45
|
+
}
|
|
46
|
+
if (error instanceof StreamError) {
|
|
47
|
+
return 500;
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof AdapterError) {
|
|
50
|
+
return 500;
|
|
51
|
+
}
|
|
52
|
+
// Check for common error patterns in message
|
|
53
|
+
const message = error.message.toLowerCase();
|
|
54
|
+
if (message.includes('invalid') || message.includes('malformed')) {
|
|
55
|
+
return 400;
|
|
56
|
+
}
|
|
57
|
+
if (message.includes('unauthorized') || message.includes('authentication')) {
|
|
58
|
+
return 401;
|
|
59
|
+
}
|
|
60
|
+
if (message.includes('forbidden') || message.includes('permission')) {
|
|
61
|
+
return 403;
|
|
62
|
+
}
|
|
63
|
+
if (message.includes('not found')) {
|
|
64
|
+
return 404;
|
|
65
|
+
}
|
|
66
|
+
if (message.includes('timeout')) {
|
|
67
|
+
return 504;
|
|
68
|
+
}
|
|
69
|
+
if (message.includes('too large')) {
|
|
70
|
+
return 413;
|
|
71
|
+
}
|
|
72
|
+
// Default to 500
|
|
73
|
+
return 500;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create error handler that logs to a custom logger
|
|
77
|
+
*/
|
|
78
|
+
export function createLoggingErrorHandler(log) {
|
|
79
|
+
return async (error, req, res) => {
|
|
80
|
+
log(`HTTP Error: ${req.method} ${req.url}`, error);
|
|
81
|
+
await defaultErrorHandler(error, req, res);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create error handler that reports errors to an external service
|
|
86
|
+
*/
|
|
87
|
+
export function createReportingErrorHandler(reporter) {
|
|
88
|
+
return async (error, req, res) => {
|
|
89
|
+
// Report error asynchronously (don't wait)
|
|
90
|
+
reporter(error, req).catch((reportError) => {
|
|
91
|
+
console.error('Error reporting failed:', reportError);
|
|
92
|
+
});
|
|
93
|
+
// Send response
|
|
94
|
+
await defaultErrorHandler(error, req, res);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Wrap error handler with custom logic
|
|
99
|
+
*/
|
|
100
|
+
export function wrapErrorHandler(baseHandler, wrapper) {
|
|
101
|
+
return async (error, req, res) => {
|
|
102
|
+
await wrapper(error, req, res, async () => {
|
|
103
|
+
await baseHandler(error, req, res);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if error should be retried
|
|
109
|
+
*/
|
|
110
|
+
export function isRetryableError(error) {
|
|
111
|
+
if (error instanceof AdapterError) {
|
|
112
|
+
return error.isRetryable;
|
|
113
|
+
}
|
|
114
|
+
if (error instanceof NetworkError || error instanceof ProviderError) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
// Check for timeout errors by message
|
|
118
|
+
if (error.message.toLowerCase().includes('timeout')) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Check if error is a client error (4xx)
|
|
125
|
+
*/
|
|
126
|
+
export function isClientError(error) {
|
|
127
|
+
const statusCode = getHTTPStatusCode(error);
|
|
128
|
+
return statusCode >= 400 && statusCode < 500;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if error is a server error (5xx)
|
|
132
|
+
*/
|
|
133
|
+
export function isServerError(error) {
|
|
134
|
+
const statusCode = getHTTPStatusCode(error);
|
|
135
|
+
return statusCode >= 500;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/error-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core HTTP Handler
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic HTTP request handler that can be adapted to any framework.
|
|
5
|
+
* Contains all the core logic for CORS, auth, rate limiting, routing, and streaming.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { RateLimiter } from './rate-limiter.js';
|
|
10
|
+
import { RouteMatcher, applyPathPrefix } from './route-matcher.js';
|
|
11
|
+
import { normalizeCORSOptions } from './cors.js';
|
|
12
|
+
import { detectProviderFormat } from './response-formatter.js';
|
|
13
|
+
/**
|
|
14
|
+
* Core HTTP request handler (framework-agnostic)
|
|
15
|
+
*/
|
|
16
|
+
export class CoreHTTPHandler {
|
|
17
|
+
bridge;
|
|
18
|
+
options;
|
|
19
|
+
rateLimiter;
|
|
20
|
+
routeMatcher;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.bridge = options.bridge;
|
|
23
|
+
// Normalize options
|
|
24
|
+
const corsOptions = normalizeCORSOptions(options.cors);
|
|
25
|
+
// Apply path prefix to routes if provided
|
|
26
|
+
let routes = options.routes;
|
|
27
|
+
if (routes && options.pathPrefix) {
|
|
28
|
+
routes = applyPathPrefix(routes, options.pathPrefix);
|
|
29
|
+
}
|
|
30
|
+
this.options = {
|
|
31
|
+
bridge: this.bridge,
|
|
32
|
+
corsOptions,
|
|
33
|
+
validateAuth: options.validateAuth,
|
|
34
|
+
onError: options.onError,
|
|
35
|
+
headers: options.headers || {},
|
|
36
|
+
timeout: options.timeout ?? 30000,
|
|
37
|
+
pathPrefix: options.pathPrefix ?? '',
|
|
38
|
+
rateLimit: options.rateLimit,
|
|
39
|
+
routes,
|
|
40
|
+
logging: options.logging ?? false,
|
|
41
|
+
log: options.log ?? (() => { }), // no-op by default
|
|
42
|
+
maxBodySize: options.maxBodySize ?? 10 * 1024 * 1024, // 10MB
|
|
43
|
+
streaming: options.streaming ?? true,
|
|
44
|
+
};
|
|
45
|
+
// Create rate limiter if configured
|
|
46
|
+
// TODO: Refactor RateLimiter to use generic types
|
|
47
|
+
this.rateLimiter = this.options.rateLimit
|
|
48
|
+
? new RateLimiter(this.options.rateLimit)
|
|
49
|
+
: null;
|
|
50
|
+
// Create route matcher if routes configured
|
|
51
|
+
this.routeMatcher = this.options.routes ? new RouteMatcher(this.options.routes) : null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Dispose of the handler and release resources.
|
|
55
|
+
* Call this when the handler is no longer needed to prevent memory leaks.
|
|
56
|
+
*/
|
|
57
|
+
dispose() {
|
|
58
|
+
if (this.rateLimiter) {
|
|
59
|
+
this.rateLimiter.dispose();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Handle HTTP request
|
|
64
|
+
*/
|
|
65
|
+
async handle(req, res) {
|
|
66
|
+
try {
|
|
67
|
+
// Handle CORS if enabled
|
|
68
|
+
if (this.options.corsOptions) {
|
|
69
|
+
const origin = req.headers.origin || req.headers['Origin'] || '';
|
|
70
|
+
// Check if origin is allowed
|
|
71
|
+
if (!this.isOriginAllowed(origin, this.options.corsOptions.origin)) {
|
|
72
|
+
res.status(403);
|
|
73
|
+
res.send({ error: 'Origin not allowed' });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Set CORS headers
|
|
77
|
+
if (typeof this.options.corsOptions.origin === 'string' &&
|
|
78
|
+
this.options.corsOptions.origin === '*') {
|
|
79
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
80
|
+
}
|
|
81
|
+
else if (origin) {
|
|
82
|
+
res.header('Access-Control-Allow-Origin', origin);
|
|
83
|
+
res.header('Vary', 'Origin');
|
|
84
|
+
}
|
|
85
|
+
if (this.options.corsOptions.credentials) {
|
|
86
|
+
res.header('Access-Control-Allow-Credentials', 'true');
|
|
87
|
+
}
|
|
88
|
+
if (this.options.corsOptions.exposedHeaders &&
|
|
89
|
+
this.options.corsOptions.exposedHeaders.length > 0) {
|
|
90
|
+
res.header('Access-Control-Expose-Headers', Array.isArray(this.options.corsOptions.exposedHeaders)
|
|
91
|
+
? this.options.corsOptions.exposedHeaders.join(', ')
|
|
92
|
+
: this.options.corsOptions.exposedHeaders);
|
|
93
|
+
}
|
|
94
|
+
// Handle preflight
|
|
95
|
+
const isPreflightRequest = req.method === 'OPTIONS' &&
|
|
96
|
+
origin &&
|
|
97
|
+
(req.headers['access-control-request-method'] ||
|
|
98
|
+
req.headers['Access-Control-Request-Method']);
|
|
99
|
+
if (isPreflightRequest) {
|
|
100
|
+
// Set preflight headers
|
|
101
|
+
res.header('Access-Control-Allow-Methods', Array.isArray(this.options.corsOptions.methods)
|
|
102
|
+
? this.options.corsOptions.methods.join(', ')
|
|
103
|
+
: this.options.corsOptions.methods);
|
|
104
|
+
const requestHeaders = req.headers['access-control-request-headers'] ||
|
|
105
|
+
req.headers['Access-Control-Request-Headers'];
|
|
106
|
+
if (requestHeaders) {
|
|
107
|
+
res.header('Access-Control-Allow-Headers', requestHeaders);
|
|
108
|
+
}
|
|
109
|
+
else if (this.options.corsOptions.allowedHeaders) {
|
|
110
|
+
res.header('Access-Control-Allow-Headers', Array.isArray(this.options.corsOptions.allowedHeaders)
|
|
111
|
+
? this.options.corsOptions.allowedHeaders.join(', ')
|
|
112
|
+
: this.options.corsOptions.allowedHeaders);
|
|
113
|
+
}
|
|
114
|
+
res.header('Access-Control-Max-Age', String(this.options.corsOptions.maxAge));
|
|
115
|
+
// Send successful preflight response
|
|
116
|
+
res.status(204);
|
|
117
|
+
res.send('');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Check rate limit
|
|
122
|
+
if (this.rateLimiter && res.isWritable()) {
|
|
123
|
+
// Create minimal Node.js-like request/response for rate limiter
|
|
124
|
+
// TODO: Refactor rate limiter to use generic types
|
|
125
|
+
const nodeReq = {
|
|
126
|
+
headers: req.headers,
|
|
127
|
+
socket: { remoteAddress: req.ip },
|
|
128
|
+
};
|
|
129
|
+
const nodeRes = {
|
|
130
|
+
setHeader: (name, value) => res.header(name, value),
|
|
131
|
+
end: (data) => {
|
|
132
|
+
if (data) {
|
|
133
|
+
res.send(JSON.parse(data));
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
get statusCode() {
|
|
137
|
+
return this._statusCode || 200;
|
|
138
|
+
},
|
|
139
|
+
set statusCode(value) {
|
|
140
|
+
this._statusCode = value;
|
|
141
|
+
res.status(value);
|
|
142
|
+
},
|
|
143
|
+
_statusCode: 200,
|
|
144
|
+
};
|
|
145
|
+
const isLimited = await this.rateLimiter.check(nodeReq, nodeRes);
|
|
146
|
+
if (isLimited) {
|
|
147
|
+
return; // Rate limiter already sent response
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Validate authentication
|
|
151
|
+
if (this.options.validateAuth) {
|
|
152
|
+
const isAuthenticated = await this.options.validateAuth(req);
|
|
153
|
+
if (!isAuthenticated) {
|
|
154
|
+
const format = detectProviderFormat(req.url || '');
|
|
155
|
+
res.status(401);
|
|
156
|
+
res.send(this.formatErrorResponse(new Error('Unauthorized'), 401, format));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Parse request (create explicit object instead of spread to ensure all properties are copied)
|
|
161
|
+
const parsedRequest = {
|
|
162
|
+
method: req.method,
|
|
163
|
+
url: req.url,
|
|
164
|
+
headers: req.headers,
|
|
165
|
+
body: req.body,
|
|
166
|
+
params: req.params,
|
|
167
|
+
query: req.query,
|
|
168
|
+
ip: req.ip,
|
|
169
|
+
stream: req.body?.stream === true,
|
|
170
|
+
};
|
|
171
|
+
// Log request if enabled
|
|
172
|
+
if (this.options.logging && this.options.log) {
|
|
173
|
+
this.options.log(`${parsedRequest.method} ${parsedRequest.url}`, parsedRequest.body);
|
|
174
|
+
}
|
|
175
|
+
// Check if request body exists for POST/PUT/PATCH
|
|
176
|
+
if (['POST', 'PUT', 'PATCH'].includes(parsedRequest.method) && !parsedRequest.body) {
|
|
177
|
+
const format = detectProviderFormat(parsedRequest.url || '');
|
|
178
|
+
res.status(400);
|
|
179
|
+
res.send(this.formatErrorResponse(new Error('Request body is required'), 400, format));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Match route if route matcher configured
|
|
183
|
+
let activeBridge = this.bridge;
|
|
184
|
+
if (this.routeMatcher) {
|
|
185
|
+
// Create minimal Node.js-like request for route matcher
|
|
186
|
+
// TODO: Refactor route matcher to use generic types
|
|
187
|
+
const nodeReq = {
|
|
188
|
+
url: req.url,
|
|
189
|
+
method: req.method,
|
|
190
|
+
};
|
|
191
|
+
const matchedRoute = this.routeMatcher.match(nodeReq);
|
|
192
|
+
if (!matchedRoute) {
|
|
193
|
+
res.status(404);
|
|
194
|
+
res.send({ error: 'Route not found' });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Use route-specific bridge if provided
|
|
198
|
+
if (matchedRoute.config.bridge) {
|
|
199
|
+
activeBridge = matchedRoute.config.bridge;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Apply custom headers
|
|
203
|
+
if (this.options.headers) {
|
|
204
|
+
for (const [key, value] of Object.entries(this.options.headers)) {
|
|
205
|
+
res.header(key, value);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Handle streaming or non-streaming request
|
|
209
|
+
if (this.options.streaming && parsedRequest.stream) {
|
|
210
|
+
// Handle streaming request
|
|
211
|
+
const stream = activeBridge.chatStream(parsedRequest.body);
|
|
212
|
+
// Convert to async generator for generic response
|
|
213
|
+
async function* convertStream() {
|
|
214
|
+
for await (const chunk of stream) {
|
|
215
|
+
yield chunk;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
await res.stream(convertStream());
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
// Handle non-streaming request
|
|
222
|
+
const response = await activeBridge.chat(parsedRequest.body);
|
|
223
|
+
// Send response
|
|
224
|
+
res.status(200);
|
|
225
|
+
res.send(response);
|
|
226
|
+
}
|
|
227
|
+
// Log response if enabled
|
|
228
|
+
if (this.options.logging && this.options.log) {
|
|
229
|
+
this.options.log(`${parsedRequest.method} ${parsedRequest.url} - 200 OK`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
// Handle errors
|
|
234
|
+
await this.handleError(error, req, res);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Handle errors
|
|
239
|
+
*/
|
|
240
|
+
async handleError(error, req, res) {
|
|
241
|
+
// Log error if enabled
|
|
242
|
+
if (this.options.logging && this.options.log) {
|
|
243
|
+
this.options.log(`Error: ${req.method} ${req.url}`, error);
|
|
244
|
+
}
|
|
245
|
+
// Call error handler
|
|
246
|
+
if (this.options.onError) {
|
|
247
|
+
await this.options.onError(error, req, res);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
// Use built-in error formatting
|
|
251
|
+
const format = detectProviderFormat(req.url || '');
|
|
252
|
+
const statusCode = this.getErrorStatusCode(error);
|
|
253
|
+
res.status(statusCode);
|
|
254
|
+
res.send(this.formatErrorResponse(error, statusCode, format));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if origin is allowed
|
|
259
|
+
*/
|
|
260
|
+
isOriginAllowed(origin, allowedOrigin) {
|
|
261
|
+
if (!origin) {
|
|
262
|
+
return true; // Allow requests without origin header
|
|
263
|
+
}
|
|
264
|
+
if (typeof allowedOrigin === 'string') {
|
|
265
|
+
return allowedOrigin === '*' || allowedOrigin === origin;
|
|
266
|
+
}
|
|
267
|
+
if (Array.isArray(allowedOrigin)) {
|
|
268
|
+
return allowedOrigin.includes(origin) || allowedOrigin.includes('*');
|
|
269
|
+
}
|
|
270
|
+
if (typeof allowedOrigin === 'function') {
|
|
271
|
+
return allowedOrigin(origin);
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Get HTTP status code from error
|
|
277
|
+
*/
|
|
278
|
+
getErrorStatusCode(error) {
|
|
279
|
+
// Check for common error patterns
|
|
280
|
+
const message = error.message.toLowerCase();
|
|
281
|
+
if (message.includes('unauthorized') || message.includes('authentication')) {
|
|
282
|
+
return 401;
|
|
283
|
+
}
|
|
284
|
+
if (message.includes('forbidden') || message.includes('permission')) {
|
|
285
|
+
return 403;
|
|
286
|
+
}
|
|
287
|
+
if (message.includes('not found')) {
|
|
288
|
+
return 404;
|
|
289
|
+
}
|
|
290
|
+
if (message.includes('timeout')) {
|
|
291
|
+
return 408;
|
|
292
|
+
}
|
|
293
|
+
if (message.includes('conflict')) {
|
|
294
|
+
return 409;
|
|
295
|
+
}
|
|
296
|
+
if (message.includes('validation') || message.includes('invalid')) {
|
|
297
|
+
return 400;
|
|
298
|
+
}
|
|
299
|
+
// Default to 500 for unknown errors
|
|
300
|
+
return 500;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Format error response in provider-specific format
|
|
304
|
+
*/
|
|
305
|
+
formatErrorResponse(error, statusCode, format) {
|
|
306
|
+
if (format === 'openai') {
|
|
307
|
+
return {
|
|
308
|
+
error: {
|
|
309
|
+
message: error.message,
|
|
310
|
+
type: 'server_error',
|
|
311
|
+
code: statusCode >= 500 ? 'internal_server_error' : 'invalid_request_error',
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
if (format === 'anthropic') {
|
|
316
|
+
return {
|
|
317
|
+
type: 'error',
|
|
318
|
+
error: {
|
|
319
|
+
type: statusCode >= 500 ? 'api_error' : 'invalid_request_error',
|
|
320
|
+
message: error.message,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
// Generic format
|
|
325
|
+
return {
|
|
326
|
+
error: error.message,
|
|
327
|
+
statusCode,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/handler.ts"],"names":[],"mappings":"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"}
|