From cce9bb7f85e23b9df4e790b1b70c39d152e6579a Mon Sep 17 00:00:00 2001 From: Andrei_Ser Date: Mon, 7 Sep 2026 19:25:39 +0400 Subject: [PATCH 1/3] demo-chat-ai-integration error-handling --- .../Angular/app/ai/ai.service.ts | 2 +- .../Angular/app/app.service.ts | 20 +++++++++++----- .../AIAndChatbotIntegration/React/service.ts | 2 +- .../AIAndChatbotIntegration/React/useApi.ts | 24 ++++++++++++------- .../ReactJs/service.js | 2 +- .../AIAndChatbotIntegration/ReactJs/useApi.js | 18 +++++++------- .../Chat/AIAndChatbotIntegration/Vue/App.vue | 21 ++++++++++------ .../AIAndChatbotIntegration/Vue/service.ts | 2 +- .../AIAndChatbotIntegration/jQuery/index.js | 22 +++++++++++------ 9 files changed, 73 insertions(+), 40 deletions(-) diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/ai/ai.service.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/ai/ai.service.ts index c90a0efe9aba..fe312c947559 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/ai/ai.service.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/ai/ai.service.ts @@ -33,7 +33,7 @@ export class AiService { temperature: 0.7, }; - const response = await this.chatService.chat.completions.create(params); + const response = await this.chatService.chat.completions.create(params, { maxRetries: 0 }); const data = { choices: response.choices }; return data.choices[0].message?.content; diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts index 20c638097558..d2d5490c7bd2 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts @@ -106,10 +106,14 @@ export class AppService { this.messages.push({ role: 'assistant', content: aiResponse }); this.renderAssistantMessage(aiResponse); }, 200); - } catch { + } catch(err: any) { this.typingUsersSubject.next([]); this.messages.pop(); - this.alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + this.alertError(errorMessage); } } @@ -135,9 +139,9 @@ export class AppService { this.dataSource.store().push([{ type: 'insert', data: message }]); } - alertLimitReached() { + alertError(message: string) { this.setAlerts([{ - message: 'Request limit reached, try again in a minute.', + message, }]); setTimeout(() => { @@ -156,9 +160,13 @@ export class AppService { this.updateLastMessage(aiResponse); this.messages.at(-1).content = aiResponse; - } catch { + } catch(err: any) { this.updateLastMessage(this.messages.at(-1).content); - this.alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + this.alertError(errorMessage); } } diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/service.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/service.ts index 37aee0842731..7d1698e6736d 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/service.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/service.ts @@ -31,7 +31,7 @@ export async function getAIResponse(messages: AIMessage[], delay?: number): Prom temperature: 0.7, }; - const response = await chatService.chat.completions.create(params); + const response = await chatService.chat.completions.create(params, { maxRetries: 0 }); const data = { choices: response.choices }; if (delay) { diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts index 03a20011b0db..7bb4b41ec38e 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts @@ -55,9 +55,9 @@ export const useApi = () => { }]); }, []); - const alertLimitReached = useCallback((): void => { + const alertError = useCallback((message: string): void => { setAlerts([{ - message: 'Request limit reached, try again in a minute.', + message, }]); setTimeout(() => { @@ -77,10 +77,14 @@ export const useApi = () => { author: assistant, text: aiResponse, }); - } catch { - alertLimitReached(); + } catch(err: any) { + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } - }, [alertLimitReached, insertMessage]); + }, [alertError, insertMessage]); const regenerateLastAIResponse = useCallback(async (): Promise => { const messageHistory = getMessageHistory(); @@ -92,11 +96,15 @@ export const useApi = () => { if (typeof aiResponse === 'string') { updateLastMessageContent(aiResponse); } - } catch { + } catch(err: any) { updateLastMessageContent(messageHistory.at(-1)?.content as string); - alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } - }, [alertLimitReached, updateLastMessageContent]); + }, [alertError, updateLastMessageContent]); return { alerts, diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/service.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/service.js index e1eeaa9fc9d1..89d12a3bcde0 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/service.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/service.js @@ -19,7 +19,7 @@ export async function getAIResponse(messages, delay) { max_completion_tokens: 1000, temperature: 0.7, }; - const response = await chatService.chat.completions.create(params); + const response = await chatService.chat.completions.create(params, { maxRetries: 0 }); const data = { choices: response.choices }; if (delay) { await wait(delay); diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js index 7f88abd8f651..3f8a33e99664 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js @@ -44,10 +44,10 @@ export const useApi = () => { }, ]); }, []); - const alertLimitReached = useCallback(() => { + const alertError = useCallback((message) => { setAlerts([ { - message: 'Request limit reached, try again in a minute.', + message, }, ]); setTimeout(() => { @@ -65,11 +65,12 @@ export const useApi = () => { author: assistant, text: aiResponse, }); - } catch { - alertLimitReached(); + } catch (err) { + const errorMessage = err.error?.message ?? err.message ?? 'Unknown error'; + alertError(errorMessage); } }, - [alertLimitReached, insertMessage], + [alertError, insertMessage], ); const regenerateLastAIResponse = useCallback(async () => { const messageHistory = getMessageHistory(); @@ -79,11 +80,12 @@ export const useApi = () => { if (typeof aiResponse === 'string') { updateLastMessageContent(aiResponse); } - } catch { + } catch (err) { updateLastMessageContent(messageHistory.at(-1)?.content); - alertLimitReached(); + const errorMessage = err.error?.message ?? err.message ?? 'Unknown error'; + alertError(errorMessage); } - }, [alertLimitReached, updateLastMessageContent]); + }, [alertError, updateLastMessageContent]); return { alerts, insertMessage, diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue index ae2196fc72eb..41471cb13298 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue @@ -125,18 +125,22 @@ async function processMessageSending( messages.push({ role: 'assistant', content: aiResponse }); renderAssistantMessage(aiResponse); }, 200); - } catch { + } catch(err: any) { typingUsers.value = []; messages.pop(); - alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } finally { toggleDisabledState(false, event); } } -function alertLimitReached(): void { +function alertError(message: string): void { alerts.value = [{ - message: 'Request limit reached, try again in a minute.', + message, }]; setTimeout(() => { @@ -156,12 +160,15 @@ async function regenerate(): Promise { if (lastMessage?.content) { lastMessage.content = aiResponse; } - } catch { + } catch(err: any) { if (lastMessage?.content) { updateLastMessage(lastMessage.content); } - - alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } finally { toggleDisabledState(false); } diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/service.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/service.ts index 89c54de11d95..269218f9ef7d 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/service.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/service.ts @@ -26,7 +26,7 @@ export async function getAIResponse(messages: AIMessage[]): Promise temperature: 0.7, }; - const response = await chatService.chat.completions.create(params as any); + const response = await chatService.chat.completions.create(params as any, { maxRetries: 0 }); const data = { choices: response.choices }; return data.choices[0].message?.content || ''; diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js index 4b0fde216add..dab6e1c546ce 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js @@ -26,16 +26,16 @@ $(() => { temperature: 0.7, }; - const response = await chatService.chat.completions.create(params); + const response = await chatService.chat.completions.create(params, { maxRetries: 0 }); const data = { choices: response.choices }; return data.choices[0].message?.content; } - function alertLimitReached() { + function alertError(message) { instance.option({ alerts: [{ - message: 'Request limit reached, try again in a minute.', + message, }], }); @@ -70,10 +70,14 @@ $(() => { renderAssistantMessage(aiResponse); }, 200); - } catch { + } catch(err) { instance.option({ typingUsers: [] }); messages.pop(); - alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } finally { toggleDisabledState(false, event); } @@ -87,9 +91,13 @@ $(() => { updateLastMessage(aiResponse); messages.at(-1).content = aiResponse; - } catch { + } catch(err) { updateLastMessage(messages.at(-1).content); - alertLimitReached(); + const errorMessage = + err.error?.message ?? + err.message ?? + "Unknown error"; + alertError(errorMessage); } finally { toggleDisabledState(false); } From 166071e13d18506099e06481615f2c29bad97bd4 Mon Sep 17 00:00:00 2001 From: Andrei_Ser Date: Mon, 7 Sep 2026 20:47:07 +0400 Subject: [PATCH 2/3] apply copilot sug --- .../Angular/app/app.service.ts | 26 ++++++++++--------- .../AIAndChatbotIntegration/React/useApi.ts | 26 ++++++++++--------- .../AIAndChatbotIntegration/ReactJs/useApi.js | 15 ++++++++--- .../Chat/AIAndChatbotIntegration/Vue/App.vue | 26 ++++++++++--------- .../AIAndChatbotIntegration/jQuery/index.js | 4 +-- 5 files changed, 55 insertions(+), 42 deletions(-) diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts index d2d5490c7bd2..87d2c84a13d7 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts @@ -106,17 +106,23 @@ export class AppService { this.messages.push({ role: 'assistant', content: aiResponse }); this.renderAssistantMessage(aiResponse); }, 200); - } catch(err: any) { + } catch (err: unknown) { this.typingUsersSubject.next([]); this.messages.pop(); - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - this.alertError(errorMessage); + this.alertError(this.getErrorMessage(err)); } } + private getErrorMessage(err: unknown): string { + if (typeof err === 'object' && err !== null) { + const e = err as { error?: { message?: unknown }; message?: unknown }; + if (typeof e.error?.message === 'string') return e.error.message; + if (typeof e.message === 'string') return e.message; + } + if (typeof err === 'string') return err; + return 'Unknown error'; + } + updateLastMessage(text = this.REGENERATION_TEXT) { const items = this.dataSource.items(); const lastMessage = items.at(-1); @@ -160,13 +166,9 @@ export class AppService { this.updateLastMessage(aiResponse); this.messages.at(-1).content = aiResponse; - } catch(err: any) { + } catch (err: unknown) { this.updateLastMessage(this.messages.at(-1).content); - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - this.alertError(errorMessage); + this.alertError(this.getErrorMessage(err)); } } diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts index 7bb4b41ec38e..23b764ce3a1d 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts @@ -38,6 +38,16 @@ const dataItemToMessage = (item: ChatTypes.Message): AIMessage => ({ const getMessageHistory = (): AIMessage[] => [...dataSource.items()].map(dataItemToMessage); +const getErrorMessage = (err: unknown): string => { + if (typeof err === 'object' && err !== null) { + const e = err as { error?: { message?: unknown }; message?: unknown }; + if (typeof e.error?.message === 'string') return e.error.message; + if (typeof e.message === 'string') return e.message; + } + if (typeof err === 'string') return err; + return 'Unknown error'; +}; + export const useApi = () => { const [alerts, setAlerts] = useState([]); @@ -77,12 +87,8 @@ export const useApi = () => { author: assistant, text: aiResponse, }); - } catch(err: any) { - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - alertError(errorMessage); + } catch (err: unknown) { + alertError(getErrorMessage(err)); } }, [alertError, insertMessage]); @@ -96,13 +102,9 @@ export const useApi = () => { if (typeof aiResponse === 'string') { updateLastMessageContent(aiResponse); } - } catch(err: any) { + } catch (err: unknown) { updateLastMessageContent(messageHistory.at(-1)?.content as string); - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - alertError(errorMessage); + alertError(getErrorMessage(err)); } }, [alertError, updateLastMessageContent]); diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js index 3f8a33e99664..0dc8fbd82f11 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js @@ -29,6 +29,15 @@ const dataItemToMessage = (item) => ({ content: item.text, }); const getMessageHistory = () => [...dataSource.items()].map(dataItemToMessage); +const getErrorMessage = (err) => { + if (typeof err === 'object' && err !== null) { + const e = err; + if (typeof e.error?.message === 'string') return e.error.message; + if (typeof e.message === 'string') return e.message; + } + if (typeof err === 'string') return err; + return 'Unknown error'; +}; export const useApi = () => { const [alerts, setAlerts] = useState([]); const insertMessage = useCallback((data) => { @@ -66,8 +75,7 @@ export const useApi = () => { text: aiResponse, }); } catch (err) { - const errorMessage = err.error?.message ?? err.message ?? 'Unknown error'; - alertError(errorMessage); + alertError(getErrorMessage(err)); } }, [alertError, insertMessage], @@ -82,8 +90,7 @@ export const useApi = () => { } } catch (err) { updateLastMessageContent(messageHistory.at(-1)?.content); - const errorMessage = err.error?.message ?? err.message ?? 'Unknown error'; - alertError(errorMessage); + alertError(getErrorMessage(err)); } }, [alertError, updateLastMessageContent]); return { diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue index 41471cb13298..6dfc70fe096d 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue @@ -108,6 +108,16 @@ function renderAssistantMessage(text: string): void { dataSource.store().push([{ type: 'insert', data: message }]); } +function getErrorMessage(err: unknown): string { + if (typeof err === 'object' && err !== null) { + const e = err as { error?: { message?: unknown }; message?: unknown }; + if (typeof e.error?.message === 'string') return e.error.message; + if (typeof e.message === 'string') return e.message; + } + if (typeof err === 'string') return err; + return 'Unknown error'; +} + async function processMessageSending( message: DxChatTypes.TextMessage, event: Events.EventObject | undefined, @@ -125,14 +135,10 @@ async function processMessageSending( messages.push({ role: 'assistant', content: aiResponse }); renderAssistantMessage(aiResponse); }, 200); - } catch(err: any) { + } catch (err: unknown) { typingUsers.value = []; messages.pop(); - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - alertError(errorMessage); + alertError(getErrorMessage(err)); } finally { toggleDisabledState(false, event); } @@ -160,15 +166,11 @@ async function regenerate(): Promise { if (lastMessage?.content) { lastMessage.content = aiResponse; } - } catch(err: any) { + } catch (err: unknown) { if (lastMessage?.content) { updateLastMessage(lastMessage.content); } - const errorMessage = - err.error?.message ?? - err.message ?? - "Unknown error"; - alertError(errorMessage); + alertError(getErrorMessage(err)); } finally { toggleDisabledState(false); } diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js index dab6e1c546ce..f1996fb43e5e 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js @@ -76,7 +76,7 @@ $(() => { const errorMessage = err.error?.message ?? err.message ?? - "Unknown error"; + 'Unknown error'; alertError(errorMessage); } finally { toggleDisabledState(false, event); @@ -96,7 +96,7 @@ $(() => { const errorMessage = err.error?.message ?? err.message ?? - "Unknown error"; + 'Unknown error'; alertError(errorMessage); } finally { toggleDisabledState(false); From 881fecb02e3cd79160181104033fbaf9c9d38a67 Mon Sep 17 00:00:00 2001 From: Andrei_Ser Date: Tue, 8 Sep 2026 17:20:45 +0400 Subject: [PATCH 3/3] fix lint --- apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js index f1996fb43e5e..04ad7dd40dd3 100644 --- a/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js +++ b/apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js @@ -70,7 +70,7 @@ $(() => { renderAssistantMessage(aiResponse); }, 200); - } catch(err) { + } catch (err) { instance.option({ typingUsers: [] }); messages.pop(); const errorMessage = @@ -91,7 +91,7 @@ $(() => { updateLastMessage(aiResponse); messages.at(-1).content = aiResponse; - } catch(err) { + } catch (err) { updateLastMessage(messages.at(-1).content); const errorMessage = err.error?.message ??