go: rate limit metadata

This commit is contained in:
Frank
2026-05-07 00:32:33 -04:00
parent 0b702704ae
commit 72ec05d0be
2 changed files with 32 additions and 9 deletions

View File

@@ -13,4 +13,13 @@ class LimitError extends Error {
} }
export class RateLimitError extends LimitError {} export class RateLimitError extends LimitError {}
export class FreeUsageLimitError extends LimitError {} export class FreeUsageLimitError extends LimitError {}
export class SubscriptionUsageLimitError extends LimitError {}
class SubscriptionUsageLimitError extends LimitError {
workspace: string
constructor(message: string, workspace: string, retryAfter?: number) {
super(message, retryAfter)
this.workspace = workspace
}
}
export class GoUsageLimitError extends SubscriptionUsageLimitError {}
export class BlackUsageLimitError extends SubscriptionUsageLimitError {}

View File

@@ -23,7 +23,8 @@ import {
ModelError, ModelError,
RateLimitError, RateLimitError,
FreeUsageLimitError, FreeUsageLimitError,
SubscriptionUsageLimitError, GoUsageLimitError,
BlackUsageLimitError,
} from "./error" } from "./error"
import { import {
buildCostChunk, buildCostChunk,
@@ -395,7 +396,8 @@ export async function handler(
if ( if (
error instanceof RateLimitError || error instanceof RateLimitError ||
error instanceof FreeUsageLimitError || error instanceof FreeUsageLimitError ||
error instanceof SubscriptionUsageLimitError error instanceof GoUsageLimitError ||
error instanceof BlackUsageLimitError
) { ) {
const headers = new Headers() const headers = new Headers()
if (error.retryAfter) { if (error.retryAfter) {
@@ -404,7 +406,14 @@ export async function handler(
return new Response( return new Response(
JSON.stringify({ JSON.stringify({
type: "error", type: "error",
error: { type: error.constructor.name, message: error.message }, error: {
type: error.constructor.name,
message: error.message,
},
metadata:
error instanceof GoUsageLimitError || error instanceof BlackUsageLimitError
? { workspace: error.workspace }
: {},
}), }),
{ status: 429, headers }, { status: 429, headers },
) )
@@ -693,10 +702,11 @@ export async function handler(
timeUpdated: sub.timeFixedUpdated, timeUpdated: sub.timeFixedUpdated,
}) })
if (result.status === "rate-limited") if (result.status === "rate-limited")
throw new SubscriptionUsageLimitError( throw new BlackUsageLimitError(
t("zen.api.error.subscriptionQuotaExceeded", { t("zen.api.error.subscriptionQuotaExceeded", {
retryIn: formatRetryTime(result.resetInSec), retryIn: formatRetryTime(result.resetInSec),
}), }),
authInfo.workspaceID,
result.resetInSec, result.resetInSec,
) )
} }
@@ -711,10 +721,11 @@ export async function handler(
timeUpdated: sub.timeRollingUpdated, timeUpdated: sub.timeRollingUpdated,
}) })
if (result.status === "rate-limited") if (result.status === "rate-limited")
throw new SubscriptionUsageLimitError( throw new BlackUsageLimitError(
t("zen.api.error.subscriptionQuotaExceeded", { t("zen.api.error.subscriptionQuotaExceeded", {
retryIn: formatRetryTime(result.resetInSec), retryIn: formatRetryTime(result.resetInSec),
}), }),
authInfo.workspaceID,
result.resetInSec, result.resetInSec,
) )
} }
@@ -739,8 +750,9 @@ export async function handler(
timeUpdated: sub.timeWeeklyUpdated, timeUpdated: sub.timeWeeklyUpdated,
}) })
if (result.status === "rate-limited") if (result.status === "rate-limited")
throw new SubscriptionUsageLimitError( throw new GoUsageLimitError(
t("zen.api.error.subscriptionQuotaExceededUseFreeModels"), t("zen.api.error.subscriptionQuotaExceededUseFreeModels"),
authInfo.workspaceID,
result.resetInSec, result.resetInSec,
) )
} }
@@ -754,8 +766,9 @@ export async function handler(
timeSubscribed: sub.timeCreated, timeSubscribed: sub.timeCreated,
}) })
if (result.status === "rate-limited") if (result.status === "rate-limited")
throw new SubscriptionUsageLimitError( throw new GoUsageLimitError(
t("zen.api.error.subscriptionQuotaExceededUseFreeModels"), t("zen.api.error.subscriptionQuotaExceededUseFreeModels"),
authInfo.workspaceID,
result.resetInSec, result.resetInSec,
) )
} }
@@ -769,8 +782,9 @@ export async function handler(
timeUpdated: sub.timeRollingUpdated, timeUpdated: sub.timeRollingUpdated,
}) })
if (result.status === "rate-limited") if (result.status === "rate-limited")
throw new SubscriptionUsageLimitError( throw new GoUsageLimitError(
t("zen.api.error.subscriptionQuotaExceededUseFreeModels"), t("zen.api.error.subscriptionQuotaExceededUseFreeModels"),
authInfo.workspaceID,
result.resetInSec, result.resetInSec,
) )
} }