Demo: chat-ai-integration imporved error handling - #35081
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
TypeScript catch(err: any) blocks and inconsistent formatting/quoting should be aligned with existing demo patterns (e.g., catch (e: unknown)) to avoid lint/style regressions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the Chat “AI and Chatbot Integration” demos to surface actual error messages in the chat alert UI, and disables OpenAI client retries so the original error is shown immediately.
Changes:
- Disable automatic retry behavior for
chat.completions.create(...)calls by passing{ maxRetries: 0 }. - Replace the hardcoded “Request limit reached…” alert with a generic
alertError(message)flow that displays the thrown error message (with fallback).
File summaries
| File | Description |
|---|---|
| apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/service.ts | Disables retries when calling chat.completions.create. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue | Shows real error messages in alerts instead of a fixed “limit reached” message. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js | Shows real error messages in alerts instead of a fixed “limit reached” message. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/service.js | Disables retries when calling chat.completions.create. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts | Shows real error messages in alerts instead of a fixed “limit reached” message. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/React/service.ts | Disables retries when calling chat.completions.create. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js | Shows real error messages in alerts and disables retries. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts | Shows real error messages in alerts instead of a fixed “limit reached” message. |
| apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/ai/ai.service.ts | Disables retries when calling chat.completions.create. |
Review details
Suppressed comments (4)
apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue:167
- Use
unknownincatchand narrow the error shape before reading properties; also fix the indentation consistency in this block.
} catch(err: any) {
if (lastMessage?.content) {
updateLastMessage(lastMessage.content);
}
const errorMessage =
apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts:103
- Prefer
catch (err: unknown)and narrow before property access (consistent with other Chat demos), rather than usingany.
} catch(err: any) {
updateLastMessageContent(messageHistory.at(-1)?.content as string);
const errorMessage =
err.error?.message ??
err.message ??
apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts:167
- Prefer
catch (err: unknown)and narrow before property access instead of usingany/unsafe property reads.
} catch(err: any) {
this.updateLastMessage(this.messages.at(-1).content);
const errorMessage =
err.error?.message ??
err.message ??
apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js:99
- Use single quotes for consistency with the rest of this file.
"Unknown error";
- Files reviewed: 9/9 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The jQuery demo’s new error handling can throw in the catch block and/or pass a non-string into alerts[].message, which can break the alert rendering and hide the original error.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js:98
- Same issue in this catch block: error extraction can produce a non-string (or throw for
null/undefinederrors), butalerts[].messageis typed asstring, so the handler should coerce/validate the value before passing it toalertError(and usecatch (err)spacing).
} catch(err) {
updateLastMessage(messages.at(-1).content);
const errorMessage =
err.error?.message ??
err.message ??
- Files reviewed: 9/9 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
The jQuery demo’s alert message derivation can still pass a non-string into dxChat.Alert.message and should normalize/coerce the error value to a string consistently.
Review details
Suppressed comments (2)
apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js:80
dxChat.Alert.messageis defined as an optionalstring, but hereerr.error?.message ?? err.messagecan produce a non-string value (e.g., object/number), which can lead to[object Object]being rendered or other unexpected behavior. Consider normalizing the error to a string (similar to thegetErrorMessagehelper used in the TS/React/Vue/Angular versions).
const errorMessage =
err.error?.message ??
err.message ??
'Unknown error';
alertError(errorMessage);
apps/demos/Demos/Chat/AIAndChatbotIntegration/jQuery/index.js:100
- Same issue as above:
err.error?.message ?? err.messageis not guaranteed to be a string, butalerts[].messageexpects astring. Normalizing the error value avoids showing[object Object]or other unintended output.
const errorMessage =
err.error?.message ??
err.message ??
'Unknown error';
alertError(errorMessage);
- Files reviewed: 9/9 changed files
- Comments generated: 0 new
- Review effort level: Lite
| }; | ||
|
|
||
| const response = await this.chatService.chat.completions.create(params); | ||
| const response = await this.chatService.chat.completions.create(params, { maxRetries: 0 }); |
There was a problem hiding this comment.
let's add maxRetries to the params object here and all next demos, where we have params object
There was a problem hiding this comment.
🟡 Changes recommended
It includes unrelated and potentially breaking demo HTML changes (removing shared vendor bundle script tags) plus a small lint-risk issue (extra semicolon) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 15/16 changed files
- Comments generated: 4
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
The removal of React/Vue vendor bundle scripts is inconsistent with other demos and likely breaks runtime, and there are a few concrete lint/style issues in the updated demo code.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (7)
Previously missed (2) — in code that hasn't changed since the last review.
apps/demos/Demos/Chat/AIAndChatbotIntegration/Angular/app/app.service.ts:116
getErrorMessageis only used insideAppService, but it’s currently public, which unnecessarily expands the service’s API surface.
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js:70- The
catchclause is on a new line (} catch (...)), which is inconsistent with the brace style used elsewhere in these demos and is likely to violatebrace-stylelint rules.
This issue also appears on line 81 of the same file.
apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/App.vue:115
getErrorMessageends with};, which leaves an extra empty statement after a function declaration and can triggerno-extra-semi/formatting lint issues.
function getErrorMessage(err: unknown): string {
if (err instanceof Error) return err.message;
if (typeof err === 'string') return err;
return 'Unknown error';
};
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/index.html:16
- This demo’s
index.htmlno longer loadsreact.vendor.js. Most other ReactJs demos still include this vendor bundle (e.g.apps/demos/Demos/Accordion/Overview/ReactJs/index.html:15), so removing it here is likely to break runtime ifbundle.jsexpects React to be provided externally.
<div class="demo-container">
<div id="app"></div>
</div>
<script src="./bundle.js"></script>
</body>
apps/demos/Demos/Chat/AIAndChatbotIntegration/Vue/index.html:16
- This demo’s
index.htmlno longer loadsvue.vendor.js. Most other Vue demos still include this vendor bundle (e.g.apps/demos/Demos/Accordion/Overview/Vue/index.html:15), so removing it here is likely to break runtime ifbundle.jsexpects Vue to be provided externally.
<div class="demo-container">
<div id="app"></div>
</div>
<script src="./bundle.js"></script>
</body>
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js:3
- The named import list has a trailing comma (
{ ..., REGENERATION_TEXT, }), which is unusual in this codebase and can cause lint failures depending on the configured style rules.
import { ALERT_TIMEOUT, assistant, REGENERATION_TEXT, } from './data.js';
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js:85
- Same brace-style issue here:
catchstarts on a new line after}. Keeping} catch (...) {on one line matches the surrounding code style and avoids likely lint failures.
}
catch (err) {
updateLastMessageContent(messageHistory.at(-1)?.content);
alertError(getErrorMessage(err));
}
- Files reviewed: 15/16 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
The ReactJs demo’s index.html drops the shared react.vendor.js include used across other ReactJs demos, which is likely to break the demo at runtime.
Review details
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/App.js:6
- This file switches import statements to double quotes, while other ReactJs demos consistently use single quotes for imports (e.g.
apps/demos/Demos/ProgressBar/Overview/ReactJs/App.js:1). Keeping the same quoting convention helps avoid churn and potential lint violations.
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/index.html:16
- The ReactJs demos typically rely on the shared React vendor bundle (react/react-dom externals). Removing the
react.vendor.jsscript tag here is likely to break the page at runtime (e.g., missing React globals / unresolved externals). Example of the established pattern:apps/demos/Demos/ProgressBar/Overview/ReactJs/index.html:15.
</div>
<script src="./bundle.js"></script>
</body>
apps/demos/Demos/Chat/AIAndChatbotIntegration/ReactJs/useApi.js:3
- There is an extra trailing comma in the import specifiers list. This is the only occurrence in
apps/demosand can fail linting / parsing depending on the toolchain target; it also looks accidental.
import { ALERT_TIMEOUT, assistant, REGENERATION_TEXT, } from './data.js';
- Files reviewed: 14/15 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
The newly introduced getErrorMessage logic can still hide real errors (e.g., empty message / non-Error objects with a message property), and the Angular regenerate flow introduces an unnecessary setTimeout delay when re-enabling the UI.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 14/14 changed files
- Comments generated: 6
- Review effort level: Lite
| } finally { | ||
| this.toggleDisabledState(false); | ||
| setTimeout(() => { | ||
| this.toggleDisabledState(false); | ||
| }); | ||
| } |
| getErrorMessage(err: unknown): string { | ||
| if (err instanceof Error) return err.message; | ||
| if (typeof err === 'string') return err; | ||
| return 'Unknown error'; | ||
| } |
| const getErrorMessage = (err: unknown): string => { | ||
| if (err instanceof Error) return err.message; | ||
| if (typeof err === 'string') return err; | ||
| return 'Unknown error'; | ||
| }; |
| const getErrorMessage = (err) => { | ||
| if (err instanceof Error) return err.message; | ||
| if (typeof err === "string") return err; | ||
| return "Unknown error"; | ||
| }; |
| function getErrorMessage(err: unknown): string { | ||
| if (err instanceof Error) return err.message; | ||
| if (typeof err === 'string') return err; | ||
| return 'Unknown error'; | ||
| } |
| function getErrorMessage(err) { | ||
| if (err instanceof Error) return err.message; | ||
| if (typeof err === 'string') return err; | ||
| return 'Unknown error'; | ||
| } |
There was a problem hiding this comment.
🟢 Approval recommended
The changes are consistent across all demo implementations and are limited to error propagation and retry configuration without altering core chat flows.
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 0 new
- Review effort level: Lite
show real error messages in the Chat alert block