fix: Adding responseMeta in query object even when the query fails - #41216
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... 📒 Files selected for processing (1)
WalkthroughPlugin and trigger error paths now include richer response context (body, params, metadata, responseData). The worker run function sanitizes thrown errors to a message-only object, optionally synchronizes ActionEntity from responseData before calling onError or rethrowing. A Cypress test was updated to assert the nested error message. Changes
Sequence Diagram(s)sequenceDiagram
participant UI
participant Saga as Saga (PluginActionSaga / EvaluationsSaga)
participant Backend as Backend/Executor
participant Worker as Worker.run
participant Store as Store/ActionEntity
UI->>Saga: trigger action
Saga->>Backend: execute request
Backend-->>Saga: error response (status, headers, body)
Note right of Saga: Enrich error payloads\n- Plugin: details = [body, params, metadata]\n- Trigger: attach responseData
Saga->>Worker: invoke run(...)
Worker->>Worker: catch(e)
alt e.responseData present
Worker->>Store: set data (responseData[0]) / responseMeta (responseData[2])\nset isLoading = false
end
alt onError provided
Worker-->>UI: call onError(original message) and return
else
Worker-->>UI: throw sanitized { message }
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Tip CodeRabbit can use oxc to improve the quality of JavaScript and TypeScript code reviews.Add a configuration file to your project to customize how CodeRabbit runs oxc. Pre-merge checks (3 passed)✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/client/src/sagas/ActionExecution/PluginActionSaga.ts (1)
636-641: Add responseMeta to onError path as well (align with PR objective).Right now, the onError branch throws PluginTriggerFailureError without metadata, so workers cannot populate action.responseMeta on failure when onError is provided. Mirror the else-branch details.
- if (onError) { - throw new PluginTriggerFailureError( - createMessage(ERROR_ACTION_EXECUTE_FAIL, pluginActionNameToDisplay), - [payload.body, params], - ); - } else { + if (onError) { + throw new PluginTriggerFailureError( + createMessage(ERROR_ACTION_EXECUTE_FAIL, pluginActionNameToDisplay), + [ + payload.body, + params, + { + isExecutionSuccess: payload.isExecutionSuccess, + statusCode: payload.statusCode, + headers: payload.headers, + }, + ], + ); + } else {
🧹 Nitpick comments (3)
app/client/src/sagas/ActionExecution/PluginActionSaga.ts (1)
648-651: Minor: normalize statusCode to string to match ActionEntity typing.ActionEntity.responseMeta.statusCode is typed string; payload.statusCode may be number.
- statusCode: payload.statusCode, + statusCode: String(payload.statusCode),app/client/src/sagas/EvaluationsSaga.ts (1)
533-538: Type-safely propagate responseData and avoid ts-expect-error.Guard the shape and keep message stringy without suppressions.
- // @ts-expect-error: reason is of type string - responsePayload.error = { - // @ts-expect-error: reason is of type string - message: error.responseData?.[0] || error.message, - // @ts-expect-error: responseData is of type array - responseData: error.responseData || [], - }; + const anyErr = error as any; + const responseData = Array.isArray(anyErr?.responseData) + ? anyErr.responseData + : []; + const first = responseData[0]; + responsePayload.error = { + message: typeof first === "string" ? first : anyErr?.message, + responseData, + };app/client/src/workers/Evaluation/fns/actionFns.ts (1)
71-90: Preserve error context and harden responseData handling.
- Keep original error.name and optionally carry responseData for downstream logs.
- Guard with Array.isArray to avoid surprises on non-array-like values.
- const error = { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - message: (e as any).message, - }; - - // If error contains responseData, update action data and responseMeta before throwing - // @ts-expect-error: responseData is a custom property - if (e.responseData && e.responseData.length > 0) { + const anyErr = e as any; + const error = { + message: anyErr?.message, + name: anyErr?.name ?? "PluginExecutionError", + } as { message: string; name: string; responseData?: unknown[] }; + + // If error contains responseData, update action data and responseMeta before throwing + const responseData = Array.isArray(anyErr?.responseData) + ? (anyErr.responseData as unknown[]) + : []; + if (responseData.length > 0) { // @ts-expect-error: self type is not defined const action = self[this.name] as ActionEntity; - // @ts-expect-error: responseData is array format - const responseData = e.responseData; - if (action && responseData.length >= 3) { action.data = responseData[0]; // error response body action.responseMeta = responseData[2]; // { isExecutionSuccess, statusCode, headers } action.isLoading = false; } + // Keep for observability if needed upstream + (error as any).responseData = responseData; }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
app/client/src/sagas/ActionExecution/PluginActionSaga.ts(1 hunks)app/client/src/sagas/EvaluationsSaga.ts(1 hunks)app/client/src/workers/Evaluation/fns/actionFns.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-08T15:32:34.115Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#35086
File: app/client/src/ce/sagas/helpers.ts:35-37
Timestamp: 2024-10-08T15:32:34.115Z
Learning: The `transformTriggerEvalErrors` function in `app/client/src/ce/sagas/helpers.ts` is typed as a generator function to maintain type safety because it gets overridden in another repository where `yield` statements are used.
Applied to files:
app/client/src/sagas/EvaluationsSaga.ts
🧬 Code graph analysis (1)
app/client/src/workers/Evaluation/fns/actionFns.ts (1)
app/client/src/ce/entities/DataTree/types.ts (1)
ActionEntity(33-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: perform-test / rts-build / build
- GitHub Check: perform-test / client-build / client-build
- GitHub Check: perform-test / server-build / server-unit-tests
- GitHub Check: client-unit-tests / client-unit-tests
- GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
- GitHub Check: client-prettier / prettier-check
- GitHub Check: client-lint / client-lint
- GitHub Check: client-build / client-build
🔇 Additional comments (2)
app/client/src/sagas/ActionExecution/PluginActionSaga.ts (1)
644-652: Nice: enriching PluginTriggerFailureError with response metadata.This enables workers to sync ActionEntity on failures. Good move.
app/client/src/workers/Evaluation/fns/actionFns.ts (1)
58-63: LGTM: updating ActionEntity on success path.Setting data, responseMeta, and isLoading=false post-exec is correct and aligns with the runtime tuple shape.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/client/cypress/**/**.*
⚙️ CodeRabbit configuration file
app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:
- Follow best practices for Cypress code and e2e automation.
- Avoid using cy.wait in code.
- Avoid using cy.pause in code.
- Avoid using agHelper.sleep().
- Use locator variables for locators and do not use plain strings.
- Use data-* attributes for selectors.
- Avoid Xpaths, Attributes and CSS path.
- Avoid selectors like .btn.submit or button[type=submit].
- Perform logins via API with LoginFromAPI.
- Perform logout via API with LogOutviaAPI.
- Perform signup via API with SignupFromAPI.
- Avoid using it.only.
- Avoid using after and aftereach in test cases.
- Use multiple assertions for expect statements.
- Avoid using strings for assertions.
- Do not use duplicate filenames even with different paths.
- Avoid using agHelper.Sleep, this.Sleep in any file in code.
Files:
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: perform-test / rts-build / build
- GitHub Check: perform-test / client-build / client-build
- GitHub Check: perform-test / server-build / server-unit-tests
- GitHub Check: client-build / client-build
- GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
- GitHub Check: client-lint / client-lint
- GitHub Check: client-unit-tests / client-unit-tests
- GitHub Check: client-prettier / prettier-check
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts (1)
35-35: Make the assertion resilient; assert stable substrings (and add a second check).Relying on "Not Found" is environment-/backend-dependent and flakes. Assert on stable substrings and add a second assertion per our Cypress guidelines (“use multiple assertions”).
- agHelper.AssertContains("404 hit : Not Found"); + // Assert on stable substrings to avoid env-specific flakes + agHelper.AssertContains("404 hit :"); + agHelper.AssertContains("404");If you add the optional
statusCodealert above, prefer asserting the actual status:- agHelper.AssertContains("404 hit : Not Found"); + agHelper.AssertContains("404 hit :"); + agHelper.AssertContains("statusCode: 404");
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/client/cypress/**/**.*
⚙️ CodeRabbit configuration file
app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:
- Follow best practices for Cypress code and e2e automation.
- Avoid using cy.wait in code.
- Avoid using cy.pause in code.
- Avoid using agHelper.sleep().
- Use locator variables for locators and do not use plain strings.
- Use data-* attributes for selectors.
- Avoid Xpaths, Attributes and CSS path.
- Avoid selectors like .btn.submit or button[type=submit].
- Perform logins via API with LoginFromAPI.
- Perform logout via API with LogOutviaAPI.
- Perform signup via API with SignupFromAPI.
- Avoid using it.only.
- Avoid using after and aftereach in test cases.
- Use multiple assertions for expect statements.
- Avoid using strings for assertions.
- Do not use duplicate filenames even with different paths.
- Avoid using agHelper.Sleep, this.Sleep in any file in code.
Files:
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: client-unit-tests / client-unit-tests
- GitHub Check: client-lint / client-lint
- GitHub Check: client-build / client-build
- GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
- GitHub Check: client-prettier / prettier-check
- GitHub Check: perform-test / client-build / client-build
- GitHub Check: perform-test / rts-build / build
- GitHub Check: perform-test / server-build / server-unit-tests
Description
Adding responseMeta in query object even when the query fails so the header request id can be used by the user, if needed.
Fixes #8024
EE PR for tests: https://github.com/appsmithorg/appsmith-ee/pull/8149
Automation
/ok-to-test tags="@tag.All"
🔍 Cypress test results
Tip
🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/17625800361
Commit: c3a972f
Cypress dashboard.
Tags:
@tag.AllSpec:
Thu, 11 Sep 2025 06:23:42 UTC
Communication
Should the DevRel and Marketing teams inform users about this change?
Summary by CodeRabbit