/** * Custom error class for chat model authentication errors */ export class ChatModelAuthError extends Error { /** * Creates a new ChatModelAuthError * * @param message - The error message * @param cause - The original error that caused this error */ constructor( message: string, public readonly cause?: unknown, ) { super(message); this.name = 'ChatModelAuthError'; // Maintains proper stack trace for where our error was thrown if (Error.captureStackTrace) { Error.captureStackTrace(this, ChatModelAuthError); } } /** * Returns a string representation of the error */ toString(): string { return `${this.name}: ${this.message}${this.cause ? ` (Caused by: ${this.cause})` : ''}`; } } export class ChatModelForbiddenError extends Error { constructor( message: string, public readonly cause?: unknown, ) { super(message); this.name = 'ChatModelForbiddenError'; if (Error.captureStackTrace) { Error.captureStackTrace(this, ChatModelForbiddenError); } } /** * Returns a string representation of the error */ toString(): string { return `${this.name}: ${this.message}${this.cause ? ` (Caused by: ${this.cause})` : ''}`; } } export const LLM_FORBIDDEN_ERROR_MESSAGE = '访问被拒绝(403禁止)。请检查: n n1。您的API密钥具有所需权限\n\n2。设置OLLAMA_ORIGINS=chrome-extension://* \nsee https://github.com/ollama/ollama/blob/main/docs/faq.md'; /** * Checks if an error is related to API authentication * * @param error - The error to check * @returns boolean indicating if it's an authentication error */ export function isAuthenticationError(error: unknown): boolean { if (!(error instanceof Error)) return false; // Get the error message const errorMessage = error.message || ''; // Get error name - sometimes error.name just returns "Error" for custom errors let errorName = error.name || ''; // Try to extract the constructor name, which often contains the actual error type // This works better than error.name for many custom errors const constructorName = error.constructor?.name; if (constructorName && constructorName !== 'Error') { errorName = constructorName; } // Check if the error name indicates an authentication error if (errorName === 'AuthenticationError') { return true; } // Fallback: check the message for authentication-related indicators return ( errorMessage.toLowerCase().includes('authentication') || errorMessage.includes(' 401') || errorMessage.toLowerCase().includes('api key') ); } /** * Checks if an error is related 403 Forbidden * * @param error - The error to check * @returns boolean indicating if it's an 403 Forbidden error */ export function isForbiddenError(error: unknown): boolean { if (!(error instanceof Error)) return false; return error.message.includes(' 403') && error.message.includes('Forbidden'); }