diff --git a/packages/backend/src/ai/llm/client/mod.rs b/packages/backend/src/ai/llm/client/mod.rs index 3d5fa548e..7140b1abf 100644 --- a/packages/backend/src/ai/llm/client/mod.rs +++ b/packages/backend/src/ai/llm/client/mod.rs @@ -693,6 +693,9 @@ impl LLMClient { if status == reqwest::StatusCode::BAD_REQUEST { return Err(BackendError::LLMClientErrorBadRequest); } + if status == reqwest::StatusCode::UNAUTHORIZED { + return Err(BackendError::LLMClientErrorUnauthorized); + } if status.is_client_error() { let error_text = response.text()?; model.provider().parse_potential_error(&error_text)?; diff --git a/packages/backend/src/lib.rs b/packages/backend/src/lib.rs index 0be3d07ef..86b0f56c1 100644 --- a/packages/backend/src/lib.rs +++ b/packages/backend/src/lib.rs @@ -28,6 +28,8 @@ pub enum BackendError { LLMClientErrorBadRequest, #[error("LLM Too Many Requests error")] LLMClientErrorTooManyRequests, + #[error("LLM Unauthorized error")] + LLMClientErrorUnauthorized, // TODO: fix this monstrosity #[error("LLM Quota Depleted error: {quotas}")] LLMClientErrorQuotasDepleted { quotas: serde_json::Value }, diff --git a/packages/backend/types/index.ts b/packages/backend/types/index.ts index 17b058ac9..fccb70b12 100644 --- a/packages/backend/types/index.ts +++ b/packages/backend/types/index.ts @@ -109,6 +109,16 @@ export class BadRequestError extends Error { } } +export class UnauthorizedError extends Error { + constructor() { + super('Unauthorized') + this.name = 'UnauthorizedError' + if (Error.captureStackTrace) { + Error.captureStackTrace(this, UnauthorizedError) + } + } +} + export interface App { id: string app_type: string diff --git a/packages/services/src/lib/ai/helpers.ts b/packages/services/src/lib/ai/helpers.ts index 4824f5ead..b1bb8e5a4 100644 --- a/packages/services/src/lib/ai/helpers.ts +++ b/packages/services/src/lib/ai/helpers.ts @@ -13,7 +13,12 @@ import { codeLanguageToMimeType, markdownToHtml, useLogScope } from '@deta/utils import { WebParser } from '@deta/web-parser' import { PromptIDs, getPrompt } from './prompts' import type { AIService } from './aiClean' -import { APIKeyMissingError, BadRequestError, TooManyRequestsError } from '@deta/backend/types' +import { + APIKeyMissingError, + BadRequestError, + TooManyRequestsError, + UnauthorizedError +} from '@deta/backend/types' import { type ChatError } from '@deta/types/src/ai.types' import { ResourceManager } from '@deta/services/resources' import { ResourceTag } from '@deta/utils/formatting' @@ -284,6 +289,10 @@ export const parseAIError = (e: any) => { } else if (e instanceof BadRequestError) { error = PageChatMessageSentEventError.BadRequest content = 'The AI server sent a bad request error. You can try again with a different query.' + } else if (e instanceof UnauthorizedError) { + error = PageChatMessageSentEventError.Unauthorized + content = + 'Unauthorized, please check your API key and make sure you have right access permissions.' } else { content = 'Encountered an unexpected error: ' + e?.message || String(e) } diff --git a/packages/services/src/lib/sffs.ts b/packages/services/src/lib/sffs.ts index 2c80aad9c..656748dd0 100644 --- a/packages/services/src/lib/sffs.ts +++ b/packages/services/src/lib/sffs.ts @@ -48,7 +48,12 @@ import type { Message, CreateChatCompletionOptions } from '@deta/backend/types' -import { APIKeyMissingError, BadRequestError, TooManyRequestsError } from '@deta/backend/types' +import { + APIKeyMissingError, + BadRequestError, + TooManyRequestsError, + UnauthorizedError +} from '@deta/backend/types' export type HorizonToCreate = Optional< HorizonData, @@ -979,6 +984,9 @@ export class SFFS { if (message.includes('LLM Too Many Requests error')) { throw new TooManyRequestsError() } + if (message.includes('LLM Unauthorized error')) { + throw new UnauthorizedError() + } } throw error } diff --git a/packages/types/src/events.types.ts b/packages/types/src/events.types.ts index 876084e61..58d39b443 100644 --- a/packages/types/src/events.types.ts +++ b/packages/types/src/events.types.ts @@ -312,6 +312,7 @@ export enum MultiSelectResourceEventAction { export enum PageChatMessageSentEventError { APIKeyMissing = 'api_key_missing', BadRequest = 'bad_request', + Unauthorized = 'unauthorized', RAGEmptyContext = 'rag_empty_context', TooManyRequests = 'too_many_requests', Other = 'other'