export type ErrorType = | 'bad_request' | 'unauthorized' | 'forbidden' | 'not_found' | 'rate_limit' | 'offline'; export type Surface = | 'chat' | 'auth' | 'api' | 'stream' | 'database' | 'history' | 'vote' | 'document' | 'suggestions'; export type ErrorCode = `${ErrorType}:${Surface}`; export type ErrorVisibility = 'response' | 'log' | 'none'; export const visibilityBySurface: Record = { database: 'log', chat: 'response', auth: 'response', stream: 'response', api: 'response', history: 'response', vote: 'response', document: 'response', suggestions: 'response', }; export class ChatSDKError extends Error { public type: ErrorType; public surface: Surface; public statusCode: number; constructor(errorCode: ErrorCode, cause?: string) { super(); const [type, surface] = errorCode.split(':'); this.type = type as ErrorType; this.cause = cause; this.surface = surface as Surface; this.message = getMessageByErrorCode(errorCode); this.statusCode = getStatusCodeByType(this.type); } public toResponse() { const code: ErrorCode = `${this.type}:${this.surface}`; const visibility = visibilityBySurface[this.surface]; const { message, cause, statusCode } = this; if (visibility === 'log') { console.error({ code, message, cause, }); return Response.json( { code: '', message: 'Something went wrong. Please try again later.' }, { status: statusCode }, ); } return Response.json({ code, message, cause }, { status: statusCode }); } } export function getMessageByErrorCode(errorCode: ErrorCode): string { if (errorCode.includes('database')) { return 'An error occurred while executing a database query.'; } switch (errorCode) { case 'bad_request:api': return "The request couldn't be processed. Please check your input and try again."; case 'unauthorized:auth': return 'You need to sign in before continuing.'; case 'forbidden:auth': return 'Your account does not have access to this feature.'; case 'rate_limit:chat': return 'You have exceeded your maximum number of messages for the day. Please try again later.'; case 'not_found:chat': return 'The requested chat was not found. Please check the chat ID and try again.'; case 'forbidden:chat': return 'This chat belongs to another user. Please check the chat ID and try again.'; case 'unauthorized:chat': return 'You need to sign in to view this chat. Please sign in and try again.'; case 'offline:chat': return "We're having trouble sending your message. Please check your internet connection and try again."; case 'not_found:document': return 'The requested document was not found. Please check the document ID and try again.'; case 'forbidden:document': return 'This document belongs to another user. Please check the document ID and try again.'; case 'unauthorized:document': return 'You need to sign in to view this document. Please sign in and try again.'; case 'bad_request:document': return 'The request to create or update the document was invalid. Please check your input and try again.'; default: return 'Something went wrong. Please try again later.'; } } function getStatusCodeByType(type: ErrorType) { switch (type) { case 'bad_request': return 400; case 'unauthorized': return 401; case 'forbidden': return 403; case 'not_found': return 404; case 'rate_limit': return 429; case 'offline': return 503; default: return 500; } }