KEMBAR78
Fix: #676 Handle text/plain response content type correctly by KariHall619 · Pull Request #677 · LinuxSuRen/api-testing · GitHub
Skip to content

Conversation

@KariHall619
Copy link
Contributor

#676

Fix text/plain response handling

Issue

When sending a request with Content-Type text/plain;charset=UTF-8, the tool incorrectly attempts to parse the response as JSON, resulting in parsing errors for non-JSON content like "测试".

Fix

Modified DefaultResponseProcess function to check the Content-Type header and handle text/plain responses appropriately:

  • For text/plain responses, use response.text() instead of response.json()
  • For other content types, continue using response.json()

Testing

Verified that GET requests to http://localhost:8080/api/hello/message?key=testMessage with text/plain responses now display correctly without JSON parsing errors.

@CLAassistant
Copy link

CLAassistant commented May 12, 2025

CLA assistant check
All committers have signed the CLA.

@LinuxSuRen
Copy link
Owner

Please feel free to add a screenshot. It's a good practice to have screenshots when you're updating the UI part.

Copy link
Owner

@LinuxSuRen LinuxSuRen left a comment

Choose a reason for hiding this comment

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

It does not work well.

image
image
image

@KariHall619
Copy link
Contributor Author

Got it! I'm locking in on it now and will have it fixed very soon!

@LinuxSuRen
Copy link
Owner

LinuxSuRen commented May 13, 2025

hi @KariHall619 , you can see also the following usage. It can close the related issue once this PR is merged.

image

See #447 and LinuxSuRen/open-source-best-practice#165


const contentType = response.headers.get('Content-Type') || '';
if (contentType.startsWith('text/plain')) {
return response.text();
Copy link
Owner

Choose a reason for hiding this comment

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

Actually it might always return in JSON format. The response is from atest itself instead of the target API. For example, when sending an HTTP GET request of https://gitee.com/linuxsuren/api-testing/raw/master/README.md, you need to check the response of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤯

Fix parsing and displaying of text/plain responses by:
- Improving text handling in DefaultResponseProcess function (net.ts)
- Adding safe JSON parsing in TestCase.vue with fallback to text display
@KariHall619 KariHall619 changed the title Fix: Handle text/plain response content type correctly Fix: #676 Handle text/plain response content type correctly May 15, 2025
- Add explicit error logging with console.debug in catch blocks
- Add detailed comments explaining intended exception handling
- Fix "Handle this exception or don't catch it at all" maintainability warnings
- Clarify that non-JSON responses are expected and properly handled
const message = await response.json().then((data: any) => data.message)
throw new Error(message)
} catch {
const text = await response.text()
Copy link
Owner

Choose a reason for hiding this comment

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

The code will always run to here due to line 37.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😢

}

// Get the complete response text first
const responseText = await response.text();
Copy link
Owner

Choose a reason for hiding this comment

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

You can get the content type, such as:

const contentType = response.headers.get('content-type') || '';

// We intentionally display as plain text instead of attempting JSON parsing
console.debug("Response body is not valid JSON, displaying as plain text:", error);
testResult.value.bodyText = e.body;
testResult.value.bodyObject = null;
Copy link
Owner

Choose a reason for hiding this comment

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

Type 'null' is not assignable to type '{}'.ts-plugin(2322)

Copy link
Owner

Choose a reason for hiding this comment

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

You can check the content type, then handle JSON or not.

image

@LinuxSuRen LinuxSuRen added the bug Something isn't working label May 18, 2025
Refactored `DefaultResponseProcess` to intelligently handle HTTP responses:

1.  Explicitly checks the 'Content-Type' header.
2.  If 'text/plain', directly processes the response as text using `response.text()`.
3.  For other content types, attempts to parse as JSON using `response.json()`.
4.  If JSON parsing fails (e.g., the content is not valid JSON despite the
    header, or it's another non-JSON type like XML), the response is
    cloned (`response.clone()`) before reading its body as text. This
    correctly handles scenarios where the initial `response.json()` call
    has already consumed the response body stream.

This approach ensures the response body is consumed only once per effective read attempt (once for text, or once for JSON attempt + once for text fallback on a cloned response if needed), resolving concerns about potential multiple reads on the original response stream and improving robustness in parsing diverse response types.
Replaced logical OR (||) with nullish coalescing operator (??)
for fetching the 'Content-Type' header in `DefaultResponseProcess`.

This change makes the assignment safer, as `??` only falls back
to the default value (empty string) if `response.headers.get('Content-Type')`
is strictly `null` or `undefined`, aligning with modern JavaScript best practices.
Refined error handling in `DefaultResponseProcess` (net.ts):
- For non-OK HTTP responses:
    - Robustly extracts error messages by attempting to parse the
      response body first as JSON, then as text, using `response.clone()`
      before each attempt to prevent stream consumption issues.
    - Logs intermediate parsing failures to `console.debug`.
    - Throws a more informative error message.
- For OK HTTP responses:
    - When falling back to text after a `response.json()` failure,
      enhanced `console.debug` logging and comments to clarify
      that this is intentional content negotiation.

These changes aim to satisfy static analysis tools regarding
unhandled exceptions by making error handling more explicit,
logging relevant information, and clarifying intent in catch blocks.
@sonarqubecloud
Copy link

Copy link
Owner

@LinuxSuRen LinuxSuRen left a comment

Choose a reason for hiding this comment

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

I have tested manually. It works well.

b1e07009-8e73-4019-ba3d-7905910ad8de

Congratulations on making your first contribution!

@LinuxSuRen LinuxSuRen merged commit 217f9f4 into LinuxSuRen:master May 25, 2025
12 of 14 checks passed
@LinuxSuRen LinuxSuRen added the ospp 开源之夏 https://summer-ospp.ac.cn/ label May 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ospp 开源之夏 https://summer-ospp.ac.cn/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error when Content-Type is text/plain; tool attempts to parse as JSON

3 participants