Skip to content

fix: Adding responseMeta in query object even when the query fails - #41216

Merged
ankitakinger merged 4 commits into
releasefrom
fix/data-response-headers-error-state
Sep 11, 2025
Merged

fix: Adding responseMeta in query object even when the query fails#41216
ankitakinger merged 4 commits into
releasefrom
fix/data-response-headers-error-state

Conversation

@ankitakinger

@ankitakinger ankitakinger commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

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.All
Spec:


Thu, 11 Sep 2025 06:23:42 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • Bug Fixes
    • Improved error messages and details when plugin actions or triggers fail, providing clearer context to diagnose issues.
    • Surfaces underlying response data on errors (when available), enabling more informative failure feedback in the UI.
    • Ensures action state is updated consistently after failures (clears loading and populates data/meta when present), preventing stale or misleading states.
    • Standardized error handling across related flows without changing successful execution behavior.

@coderabbitai

coderabbitai Bot commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

📥 Commits

Reviewing files that changed from the base of the PR and between 9f5ab2c and c3a972f.

📒 Files selected for processing (1)
  • app/client/src/sagas/EvaluationsSaga.ts (1 hunks)
 ________________________________________________________
< Rust’s borrow checker and I are on a first-name basis. >
 --------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Walkthrough

Plugin 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

Cohort / File(s) Summary
Plugin action error details
app/client/src/sagas/ActionExecution/PluginActionSaga.ts
On plugin action failure (isError path), pass a non-empty details array containing request body, params, and a metadata object (isExecutionSuccess, statusCode, headers) to PluginTriggerFailureError instead of an empty array.
Trigger request error payload
app/client/src/sagas/EvaluationsSaga.ts
In the catch block, attach error.responseData (or []) to the thrown error payload; message extraction remains `error.responseData?.[0]
Worker error handling & state sync
app/client/src/workers/Evaluation/fns/actionFns.ts
run now throws a sanitized error object { message } instead of the raw error. If e.responseData exists, the worker optionally updates the associated ActionEntity (sets data, responseMeta, isLoading=false) using indices from responseData before invoking onError or rethrowing. onError handling remains supported.
Test assertion update
app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts
Catch handler now references e.message.message; assertion updated to expect the nested message ("Not Found") and reformatted to a multi-line agHelper.AssertContains call.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

Errors now carry maps and signs,
Bodies, headers, indexed lines.
Workers tidy, trim the fray—
Sync the state, then pass the day.
Cleaner traces, sharper clues.

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)
Check name Status Explanation
Title Check ✅ Passed The title precisely reflects the core change by indicating that responseMeta will now be included in the query object on failures, directly matching the PR’s intent and avoiding unnecessary detail or extraneous file names.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed The PR description includes the required "## Description" heading and succinctly explains the change (adding responseMeta on failed queries) while linking the related issue (#8024) and the EE PR for tests. The "## Automation" section is present with the /ok-to-test tag and the auto-generated "Cypress test results" block is included. Overall the description conforms to the repository template and is sufficiently complete for review, though a few clarifying details could improve reviewer context.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/data-response-headers-error-state

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ankitakinger ankitakinger added the ok-to-test Required label for CI label Sep 10, 2025
@github-actions github-actions Bot added the Bug Something isn't working label Sep 10, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d1401ea and 8f13b53.

📒 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f13b53 and acf5e4e.

📒 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

Comment thread app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 statusCode alert 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

📥 Commits

Reviewing files that changed from the base of the PR and between acf5e4e and 9f5ab2c.

📒 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

Comment thread app/client/cypress/e2e/Regression/ClientSide/BugTests/CatchBlock_Spec.ts Outdated
Comment thread app/client/src/workers/Evaluation/fns/actionFns.ts
@ankitakinger
ankitakinger merged commit e1cb5d9 into release Sep 11, 2025
159 of 162 checks passed
@ankitakinger
ankitakinger deleted the fix/data-response-headers-error-state branch September 11, 2025 07:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working ok-to-test Required label for CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants