codeant-ai-for-open-source[bot] commented on code in PR #37131:
URL: https://github.com/apache/superset/pull/37131#discussion_r3402738627


##########
superset-frontend/packages/superset-ui-core/src/connection/SupersetClientClass.ts:
##########
@@ -150,6 +150,25 @@ export default class SupersetClientClass {
     }
   }
 
+  /**
+   * POST request that returns a blob for file downloads.
+   * Unlike postForm, this uses AJAX so errors can be caught and handled.
+   * @param endpoint - API endpoint
+   * @param payload - Request payload
+   * @returns Promise resolving to Response with blob
+   */
+  async postBlob(
+    endpoint: string,
+    payload: Record<string, any>,
+  ): Promise<Response> {
+    await this.ensureAuth();
+    return this.post({
+      endpoint,
+      postPayload: payload,
+      parseMethod: 'raw',
+    });

Review Comment:
   **Suggestion:** `postBlob` forwards `postPayload` without overriding the 
default `stringify: true`, so string fields are JSON-stringified again by 
`callApi`. Export callers already pass `form_data` as a JSON string, which 
becomes double-encoded (extra quotes), and the backend then parses it as a 
string instead of an object, causing export requests to fail (typically 400) 
instead of downloading. Pass `stringify: false` (or send a prebuilt `FormData`) 
to preserve raw form field values. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Dashboard chart CSV export returns HTTP 400, no download.
   - ❌ Explore view chart exports fail against /api/v1/chart/data.
   - ⚠️ Users see error toasts instead of downloaded export files.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open a dashboard and trigger CSV export for a chart; tests at
   
`superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.test.tsx:8-31`
 show
   that clicking "Export to .CSV" calls `exportChart(...)` from
   `src/explore/exploreUtils/index.ts`.
   
   2. In
   
`superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.tsx:19-37,559-567`,
   the `exportChart` function is invoked with `resultFormat: 'csv'` and 
`resultType: 'full'`,
   and `onStartStreamingExport` left as `null`, so the non-streaming export 
path is used.
   
   3. Inside `superset-frontend/src/explore/exploreUtils/index.ts:18-69`, 
`exportChart`
   builds the payload and, for the v1 API (`url = '/api/v1/chart/data'`), calls
   `SupersetClient.postBlob(url as string, { form_data: safeStringify(payload) 
})` at lines
   41-47 and 65-67, where `safeStringify` (see
   `plugins/preset-chart-deckgl/src/utils/safeStringify.ts:4-24`) returns a 
JSON string.
   
   4. `SupersetClient.postBlob` in
   `packages/superset-ui-core/src/connection/SupersetClientClass.ts:160-169` 
forwards this
   payload via `this.post({ endpoint, postPayload: payload, parseMethod: 'raw' 
})` without
   specifying `stringify`, so `request` flows into `callApiAndParseWithTimeout` 
and then
   `callApi` in 
`packages/superset-ui-core/src/connection/callApi/callApi.ts:8-23,80-100`,
   where `stringify` defaults to `true` and each form field value is 
transformed with
   `valueString = stringify ? JSON.stringify(value) : String(value)`, causing 
`form_data`
   (already a JSON string) to be JSON-stringified again and sent as `'"{...}"'` 
in the
   multipart form body.
   
   5. On the backend, `superset/charts/data/api.py:47-55` handles 
`/api/v1/chart/data` POST
   requests by checking `request.form.get("form_data")` and running
   `json.loads(request.form["form_data"])`; with the double-encoded payload 
this produces a
   plain string instead of a dict, so `_create_query_context_from_form` (which 
expects a
   dict, see `superset/tasks/async_queries.py:1-14`) raises a 
`ValidationError`, and
   `ChartDataRestApi.data` catches this and returns `self.response_400(...)`, 
causing the
   chart export HTTP 400 error and preventing the file from downloading.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=e7b9856f660c40e4b8dcb258ecd148d2&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 | [Fix in VSCode 
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=e7b9856f660c40e4b8dcb258ecd148d2&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/connection/SupersetClientClass.ts
   **Line:** 165:169
   **Comment:**
        *Api Mismatch: `postBlob` forwards `postPayload` without overriding the 
default `stringify: true`, so string fields are JSON-stringified again by 
`callApi`. Export callers already pass `form_data` as a JSON string, which 
becomes double-encoded (extra quotes), and the backend then parses it as a 
string instead of an object, causing export requests to fail (typically 400) 
instead of downloading. Pass `stringify: false` (or send a prebuilt `FormData`) 
to preserve raw form field values.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37131&comment_hash=8b1f48b41e65b204a160b00ca6d3fd7fdc21765f471ee95fb8e94beee87fca14&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37131&comment_hash=8b1f48b41e65b204a160b00ca6d3fd7fdc21765f471ee95fb8e94beee87fca14&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to