|
@@ -28,3 +28,73 @@ export class ChatModelAuthError extends Error {
|
|
return `${this.name}: ${this.message}${this.cause ? ` (Caused by: ${this.cause})` : ''}`;
|
|
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 =
|
|
|
|
+ 'Access denied (403 Forbidden). Please check:\n\n1. Your API key has the required permissions\n\n2. For Ollama: Set 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');
|
|
|
|
+}
|