Skip to content

Conversation

@adev-code
Copy link
Contributor

@adev-code adev-code commented Nov 25, 2025

Problem

When services return 4XX errors with empty or malformed XML bodies, users receive parser errors that hide the actual service response. Instead of seeing the real HTTP error from the service, users get XML parsing failures:

botocore.parsers.ResponseParserError: Unable to parse response (no element found: line 1, column 0), invalid XML received. 
Further retries may succeed: b''

The error is returned from def _parse_xml_string_to_dom(self, xml_string):.

The actual service response (for example: HTTP 413: Content Too Large) is completely hidden from users, making it hard to understand why their request failed.

An example of occurrence: CloudWatch's put_dashboard API when the request body exceeds size limits.

Solution

This PR surfaces the actual HTTP error response from the service by adding HTTP status context. Users now see both the parsing error and the real service error that caused it:

botocore.parsers.ResponseParserError: Unable to parse response (no element found: line 1, column 0), invalid XML received. Further retries may succeed:
b'' (HTTP 413: Content Too Large)

Now users can see that their request failed because the content was too large (the real service error: HTTP 413: Content Too Large).

Note

  • Backwards Compatibility: Preserves the Original Error. Added error context alongside the original error.

When XML parsing fails due to empty or malformed responses, users now
receive the actual HTTP error response from the service alongside the
parsing error, providing useful information about what actually happened.

Before:
  ResponseParserError: Unable to parse response (no element found:
  line 1, column 0), invalid XML received. Further retries may succeed: b''

After:
  ResponseParserError: Unable to parse response (no element found:
  line 1, column 0), invalid XML received. Further retries may succeed: b''
  HTTP 413: Content Too Large

This exposes the real service error (HTTP 413: Content Too Large) that
was previously hidden behind cryptic XML parsing failures, giving users
actionable information about why their request failed.
@adev-code adev-code changed the title Add HTTP status context to XML parsing errors for better 4XX error handling Add HTTP status context to XML parsing errors. Nov 25, 2025
@adev-code adev-code changed the title Add HTTP status context to XML parsing errors. Add HTTP status context to XML parsing errors Nov 25, 2025
@codecov-commenter
Copy link

codecov-commenter commented Nov 25, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.71%. Comparing base (8121342) to head (854b868).
⚠️ Report is 125 commits behind head on develop.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3602      +/-   ##
===========================================
- Coverage    93.17%   92.71%   -0.46%     
===========================================
  Files           68       68              
  Lines        15411    15571     +160     
===========================================
+ Hits         14359    14437      +78     
- Misses        1052     1134      +82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The HTTP 413 status message differs between Python versions:
- Python 3.13: "Content Too Large"
- Python 3.11: "Request Entity Too Large"

Updated test assertions to use assertIn("HTTP 413:") instead of exact
string matching to ensure tests pass across supported Python versions
while still verifying that HTTP status context is properly added to
XML parsing errors.
Add hasattr(e, 'add_note') checks before calling add_note() to ensure
compatibility with Python 3.9 and 3.10 where PEP 678 exception notes
are not available. The enhanced HTTP status context will only be added
in Python 3.11+ while maintaining backward compatibility.
response['status_code'], ''
)
if status_message:
if status_message and hasattr(e, 'add_note'):
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this requires Python 3.11+ so this is probably not the approach we want to take to make sure this works everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks Nate, yes I only found out from the CI tests and trying options. Will check for other ways.

Enhanced ResponseParserError messages to include HTTP status codes and
messages when XML parsing fails, providing better debugging context for
users while maintaining full backward compatibility.

Changes:
- Modified QueryParser._do_error_parse() to append HTTP status context
- Modified RestXMLParser._parse_error_from_body() to append HTTP status context
- Enhanced error messages format: "original error (HTTP 413: Content Too Large)"
- Preserves original ResponseParserError exception type for compatibility
- Added comprehensive tests for both parser classes
- Tests handle Python version differences in HTTP status messages
- Improve code readability while maintaining identical functionality
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants