Skip to content

Commit

Permalink
Custom error type for bad request errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
manugoyal committed Dec 4, 2024
1 parent 82c1a67 commit 229f98b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
29 changes: 17 additions & 12 deletions packages/proxy/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
APISecret,
} from "@schema";
import {
ProxyBadRequestError,
flattenChunks,
flattenChunksArray,
getRandomInt,
Expand Down Expand Up @@ -171,7 +172,7 @@ export async function proxyV1({

const authToken = parseAuthHeader(proxyHeaders);
if (!authToken) {
throw new Error("Missing Authentication header");
throw new ProxyBadRequestError("Missing Authentication header");
}

// Caching is enabled by default, but let the user disable it
Expand Down Expand Up @@ -363,7 +364,7 @@ export async function proxyV1({
}

if (streamFormat === "vercel-ai" && !isStreaming) {
throw new Error(
throw new ProxyBadRequestError(
"Vercel AI format requires the stream parameter to be set to true",
);
}
Expand Down Expand Up @@ -778,7 +779,7 @@ async function fetchModelLoop(
endpointUrl = "/completions";
break;
default:
throw new Error(
throw new ProxyBadRequestError(
`Unsupported model ${model} (must be chat or completion for /auto endpoint)`,
);
}
Expand Down Expand Up @@ -895,7 +896,7 @@ async function fetchModelLoop(
if (lastException) {
throw lastException;
} else {
throw new Error(
throw new ProxyBadRequestError(
`No API keys found (for ${model}). You can configure API secrets at https://www.braintrust.dev/app/settings?subroute=secrets`,
);
}
Expand Down Expand Up @@ -955,7 +956,7 @@ async function fetchModel(
console.assert(method === "POST");
return await fetchGoogle("POST", url, headers, bodyData, secret);
default:
throw new Error(`Unsupported model provider ${format}`);
throw new ProxyBadRequestError(`Unsupported model provider ${format}`);
}
}

Expand All @@ -973,7 +974,7 @@ async function fetchOpenAI(
secret.metadata.api_base) ||
EndpointProviderToBaseURL[secret.type];
if (baseURL === null) {
throw new Error(
throw new ProxyBadRequestError(
`Unsupported provider ${secret.name} (${secret.type}) (must specify base url)`,
);
}
Expand All @@ -989,7 +990,7 @@ async function fetchOpenAI(
model.replace("gpt-3.5", "gpt-35"),
)}`;
} else {
throw new Error(
throw new ProxyBadRequestError(
`Azure provider ${secret.id} must have a deployment or model specified`,
);
}
Expand Down Expand Up @@ -1180,7 +1181,9 @@ async function fetchAnthropic(
headers["x-api-key"] = secret.secret;

if (isEmpty(bodyData)) {
throw new Error("Anthropic request must have a valid JSON-parsable body");
throw new ProxyBadRequestError(
"Anthropic request must have a valid JSON-parsable body",
);
}

const {
Expand All @@ -1201,7 +1204,7 @@ async function fetchAnthropic(
m.role === "function" ||
("function_call" in m && !isEmpty(m.function_call))
) {
throw new Error(
throw new ProxyBadRequestError(
"Anthropic does not support function messages or function_calls",
);
} else if (m.role === "tool") {
Expand All @@ -1217,7 +1220,7 @@ async function fetchAnthropic(
!translatedRole ||
!(translatedRole === "user" || translatedRole === "assistant")
) {
throw new Error(`Unsupported Anthropic role ${role}`);
throw new ProxyBadRequestError(`Unsupported Anthropic role ${role}`);
}

messages.push({
Expand Down Expand Up @@ -1332,7 +1335,9 @@ async function fetchGoogle(
console.assert(url === "/chat/completions");

if (isEmpty(bodyData)) {
throw new Error("Google request must have a valid JSON-parsable body");
throw new ProxyBadRequestError(
"Google request must have a valid JSON-parsable body",
);
}

const {
Expand Down Expand Up @@ -1522,7 +1527,7 @@ function parseEnumHeader<T>(
): (typeof headerTypes)[number] {
const header = value && value.toLowerCase();
if (header && !headerTypes.includes(header as T)) {
throw new Error(
throw new ProxyBadRequestError(
`Invalid ${headerName} header '${header}'. Must be one of ${headerTypes.join(
", ",
)}`,
Expand Down
6 changes: 6 additions & 0 deletions packages/proxy/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ export function isEmpty(a: any): a is null | undefined {
export function getRandomInt(max: number) {
return Math.floor(Math.random() * max);
}

export class ProxyBadRequestError extends Error {
constructor(public message: string) {
super(message);
}
}

0 comments on commit 229f98b

Please sign in to comment.