fix(ui): guard missing Axios error.response in ToolDialog error handlers#6482
fix(ui): guard missing Axios error.response in ToolDialog error handlers#6482chatman-media wants to merge 2 commits into
Conversation
When a network request fails at the transport level (timeout, CORS block, cancelled request, offline) Axios sets error.response to undefined. Catch blocks in ToolDialog.jsx read error.response.data directly, so a secondary TypeError is thrown inside the error handler itself, masking the real failure and leaving users with no feedback. Changes: - Add getAxiosErrorMessage() to packages/ui/src/utils/errorHandler.js. It safely extracts a message by checking response?.data?.message, response?.data?.error, a plain string body, then error.message, and finally a generic fallback — never assuming response is defined. - Replace all four bare error.response.data accesses in packages/ui/src/views/tools/ToolDialog.jsx (exportTool, addNewTool, saveTool, deleteTool) with getAxiosErrorMessage(error). - Add packages/ui/src/utils/errorHandler.test.js with 10 unit tests covering the new helper (undefined response, null error, structured data, plain string body, generic fallback). Closes FlowiseAI#6466
There was a problem hiding this comment.
Code Review
This pull request introduces a centralized getAxiosErrorMessage utility function to safely extract human-readable messages from Axios errors, along with a comprehensive suite of unit tests. It also refactors ToolDialog.jsx to replace repetitive inline error-handling logic with this new utility. Feedback on the PR suggests making the getAxiosErrorMessage function more robust by handling nested error objects and array messages to prevent rendering issues like [object Object] in the UI.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| export const getAxiosErrorMessage = (error) => { | ||
| if (error?.response?.data) { | ||
| const data = error.response.data | ||
| if (typeof data === 'object') { | ||
| return data.message || data.error || getErrorMessage(error) | ||
| } | ||
| return String(data) | ||
| } | ||
| return error?.message || 'An unexpected error occurred' | ||
| } |
There was a problem hiding this comment.
If the API returns a nested error object (e.g., { error: { message: '...' } } which is common in OpenAI and other standard APIs) or an array of messages (e.g., ['error 1', 'error 2'] in NestJS validation errors), the current implementation will return the object or array directly. When interpolated into a string in the UI, this results in [object Object] or unformatted output.
We can make getAxiosErrorMessage more robust by safely resolving nested error objects and joining array messages with commas.
| export const getAxiosErrorMessage = (error) => { | |
| if (error?.response?.data) { | |
| const data = error.response.data | |
| if (typeof data === 'object') { | |
| return data.message || data.error || getErrorMessage(error) | |
| } | |
| return String(data) | |
| } | |
| return error?.message || 'An unexpected error occurred' | |
| } | |
| export const getAxiosErrorMessage = (error) => { | |
| if (error?.response?.data) { | |
| const data = error.response.data | |
| if (typeof data === 'object' && data !== null) { | |
| const rawMessage = data.message || (typeof data.error === 'object' ? data.error?.message || data.error?.error : data.error) | |
| if (rawMessage) { | |
| if (Array.isArray(rawMessage)) { | |
| return rawMessage.join(', ') | |
| } | |
| if (typeof rawMessage === 'object') { | |
| return JSON.stringify(rawMessage) | |
| } | |
| return String(rawMessage) | |
| } | |
| return getErrorMessage(error) | |
| } | |
| return String(data) | |
| } | |
| return error?.message || 'An unexpected error occurred' | |
| } |
References
- When using a heuristic for detection (e.g., for content type), ensure a safe fallback mechanism is in place to correctly handle cases where the heuristic fails.
…ssage
Handle APIs that nest the message ({ error: { message } }) or return an array of
messages (NestJS validation) so the UI never renders [object Object].
Addresses gemini-code-assist review on FlowiseAI#6466
Closes #6466
Problem
Catch blocks in
packages/ui/src/views/tools/ToolDialog.jsxaccesserror.response.datawithout checking whethererror.responseexists first:Axios only sets
error.responsewhen the server actually returned an HTTP response. On network failures, timeouts, CORS blocks, and cancelled requestserror.responseisundefined, so the code above throws a secondaryTypeErrorinside the catch block itself. This masks the real failure and leaves the user with no toast notification.Fix
1.
packages/ui/src/utils/errorHandler.js— addsgetAxiosErrorMessage(error):Priority:
response.data.message→response.data.error→ plain string body →error.message→ generic fallback. Never assumesresponseis defined.2.
packages/ui/src/views/tools/ToolDialog.jsx— replaces all four unsafe accesses (inexportTool,addNewTool,saveTool,deleteTool) withgetAxiosErrorMessage(error).3.
packages/ui/src/utils/errorHandler.test.js— adds 10 focused unit tests:error.responseisundefinederrorisnull/undefinedresponse.data.message(structured API error)response.data.errorerror.messageVerification
All 10 unit tests pass (
jest --testPathPattern=errorHandler.test):Prettier reports all changed files as
(unchanged)— style already conforms to the project config.🤖 Generated with Claude Code