| import { Request, Response } from "express"; |
| import * as http from "http"; |
| import * as httpProxy from "http-proxy"; |
| import { logger } from "../logger"; |
| import { keys } from "../keys"; |
|
|
| |
| export const handleResponse = ( |
| proxyRes: http.IncomingMessage, |
| req: Request, |
| res: Response |
| ) => { |
| const statusCode = proxyRes.statusCode || 500; |
| if (statusCode >= 400) { |
| let body = ""; |
| proxyRes.on("data", (chunk) => (body += chunk)); |
| proxyRes.on("end", () => { |
| let errorPayload: any = { |
| error: "Proxy couldn't parse error from OpenAI", |
| }; |
| const canTryAgain = keys.anyAvailable() |
| ? "You can try again to get a different key." |
| : "There are no more keys available."; |
| try { |
| errorPayload = JSON.parse(body); |
| } catch (err) { |
| logger.error({ error: err }, errorPayload.error); |
| res.json(errorPayload); |
| return; |
| } |
|
|
| if (statusCode === 401) { |
| |
| logger.warn( |
| `OpenAI key is invalid or revoked. Keyhash ${req.key?.hash}` |
| ); |
| keys.disable(req.key!); |
| const message = `The OpenAI key is invalid or revoked. ${canTryAgain}`; |
| errorPayload.proxy_note = message; |
| } else if (statusCode === 429) { |
| |
| |
| |
| |
| |
| if (errorPayload.error?.type === "insufficient_quota") { |
| logger.warn(`OpenAI key is exhausted. Keyhash ${req.key?.hash}`); |
| keys.disable(req.key!); |
| const message = `The OpenAI key is exhausted. ${canTryAgain}`; |
| errorPayload.proxy_note = message; |
| } else { |
| logger.warn( |
| { errorCode: errorPayload.error?.type }, |
| `OpenAI rate limit exceeded or model overloaded. Keyhash ${req.key?.hash}` |
| ); |
| } |
| } |
|
|
| res.status(statusCode).json(errorPayload); |
| }); |
| } else { |
| |
| keys.incrementPrompt(req.key?.hash); |
|
|
| Object.keys(proxyRes.headers).forEach((key) => { |
| res.setHeader(key, proxyRes.headers[key] as string); |
| }); |
| proxyRes.pipe(res); |
| } |
| }; |
|
|
| export const onError: httpProxy.ErrorCallback = (err, _req, res) => { |
| logger.error({ error: err }, "Error proxying to OpenAI"); |
|
|
| (res as http.ServerResponse).writeHead(500, { |
| "Content-Type": "application/json", |
| }); |
| res.end( |
| JSON.stringify({ |
| error: { |
| type: "proxy_error", |
| message: err.message, |
| proxy_note: |
| "Reverse proxy encountered an error before it could reach OpenAI.", |
| }, |
| }) |
| ); |
| }; |
|
|