Skip to content

Include pushgateway response body in HTTP error messages - #1198

Open
aviseth wants to merge 1 commit into
prometheus:masterfrom
aviseth:fix/issue-96
Open

Include pushgateway response body in HTTP error messages#1198
aviseth wants to merge 1 commit into
prometheus:masterfrom
aviseth:fix/issue-96

Conversation

@aviseth

@aviseth aviseth commented Aug 10, 2026

Copy link
Copy Markdown

@csmarchbanks this is #96, which has been open a long time, so tell me if it is no longer wanted and I will close it.

When the pushgateway rejects a push it says why in the response body: text format parsing error in line 3: expected float as value, a complaint about a duplicate metric name, and so on. urllib raises HTTPError from inside opener.open(), and HTTPError.__str__ renders only HTTP Error 500: Internal Server Error, so the explanation is gone by the time the exception reaches the caller. Most code logs the traceback, and with it the one piece of information that would have said what was wrong with the payload.

_make_handler now catches HTTPError, reads the body, and re-raises HTTPError with the body appended to the reason. The type is unchanged, so except HTTPError, except OSError and except IOError call sites keep working and only the message text differs. An empty body re-raises the original untouched. The resp.code >= 400 branch below is only reachable with a base_handler that suppresses urllib's default error handling, but it had the same problem, so it gets the same treatment.

test_push_error_includes_response_body drives a 500 with a body through the TestPushGateway stub handler, which already branches on the request line, and checks that the body text lands in str(exception) and that it is still an HTTPError with .code == 500. Nothing exercised a >= 400 response from the gateway before this.

Two things I did not want to decide on my own.

The body is not truncated. A reverse proxy in front of the gateway can return a full HTML error page, and all of it would end up in the message. I am glad to cap it if you want one, but the limit is your call.

e.read() consumes the response, so the replacement HTTPError is constructed with fp=None. Anyone currently writing except HTTPError as e: e.read() to get at the body would get an empty read instead. The text is in str(e) now, but it is a behaviour change and you may want it handled another way.

Fixes #96

When the pushgateway rejects a push it explains why in the response body,
but urllib's HTTPError only renders "HTTP Error 500: Internal Server
Error", so the diagnostic was discarded before the caller ever saw it.
Read the body in _make_handler and append it to the error message, still
raising an HTTPError so existing except clauses keep working, and include
the body in the OSError raised for handlers that suppress urllib's default
error handling.

Fixes prometheus#96

Signed-off-by: Avi Seth <avi.seth8@gmail.com>
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.

Print out response body when a 500 Internal Server Error is received from the pushgateway

1 participant