reviewer: surface GitHub error details when publish_review fails (#1282)

post_pull_request_review used to swallow the HTTPError and return None,
so the tool result was just "Failed to POST PR review" with no status
or body — the actual cause (e.g. 422 invalid inline comment, 404 app
not installed) only lived in logs. Capture status + body and propagate
into the tool result so the agent (and traces) can see why.
This commit is contained in:
Johannes du Plessis 2026-05-08 15:40:05 -07:00 • committed by GitHub
parent 094b2df939
commit 3f319b7d8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 2 deletions

View file

@ -122,9 +122,20 @@ async def post_pull_request_review(
try:
response = await client.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
except httpx.HTTPError:
except httpx.HTTPStatusError as e:
body = (e.response.text or "")[:500]
logger.exception(
"Failed to POST PR review for %s/%s#%s: %s %s",
owner,
repo,
pr_number,
e.response.status_code,
body,
)
return {"_error": f"HTTP {e.response.status_code}: {body}"}
except httpx.HTTPError as e:
logger.exception("Failed to POST PR review for %s/%s#%s", owner, repo, pr_number)
return None
return {"_error": f"{type(e).__name__}: {e}"}
data = response.json()
return data if isinstance(data, dict) else None

View file

@ -159,6 +159,11 @@ async def _publish_review_async(
)
if review_response is None:
return {"success": False, "error": "Failed to POST PR review"}
if isinstance(review_response, dict) and "_error" in review_response:
return {
"success": False,
"error": f"Failed to POST PR review: {review_response['_error']}",
}
review_id = review_response.get("id") if isinstance(review_response, dict) else None
if review_id is not None and inline_comments: