fix[bug]: handle non-JSON responses and query params in REST tools (#3855, #3857) #3873
fix[bug]: handle non-JSON responses and query params in REST tools (#3855, #3857) #3873brian-hussey merged 6 commits intomainfrom
Conversation
18c39b4 to
ffaf721
Compare
9118d23 to
3cc84d2
Compare
c1b46f9 to
42a7212
Compare
TS0713
left a comment
There was a problem hiding this comment.
-
Fixes the Admin UI issue where Test/Invoke buttons were not working — the missing invokeTool() and runToolTest() functions are now properly added, and the request format is corrected to tools/call. I verified this flow manually and it’s working end-to-end now.
-
Fixes the REST POST query parameter issue — query params are now correctly preserved in the URL for POST/PUT requests. I tested this as well, and signed URL / query-based APIs are working as expected.
-
Handles non-JSON responses (HTML, text, etc.) — prevents crashes and makes the system more robust.
-
Manually tested on gateway admin UI by adding REST tools - 1 with query params and other returns HTML result as part of final response - Both working as expected
Overall, these are useful fixes across both UI and backend, and everything looks clean and well-tested.
I approve this PR.
92aa952 to
b35348c
Compare
afaf664 to
8490829
Compare
8490829 to
416641a
Compare
crivetimihai
left a comment
There was a problem hiding this comment.
Nice work on this one — the core idea of handling non-JSON REST responses and fixing query param handling for signed URLs is solid and well-motivated.
What I changed during rebase
The branch had significant merge conflicts since admin.js was split into ES modules (#3137) after this PR was opened. I rebased onto current main, squashed the 22 commits into one clean commit, and made the following adjustments:
JS changes ported to modular structure
- All JS changes now target
mcpgateway/admin_ui/tools.jsandadmin_ui/admin.jsinstead of the old monolithicadmin.js - Used
fetchWithTimeout(already imported) instead of rawfetch+getCookiefor consistency with the existingtestTool()function - Replaced
innerHTMLassignments with safe DOM methods (removeChild,createElement,textContent) to avoid XSS vectors
Fixed unreachable 4xx/5xx error handling (critical)
The original code placed the non-JSON error response handling after response.raise_for_status(), which throws httpx.HTTPStatusError for 4xx/5xx — making the error branch unreachable for the exact cases #3855 describes.
Fixed by catching HTTPStatusError and handling the error response in the except block:
- Parses body with the same JSON/non-JSON fallback
- Includes HTTP status code in the error message (
"HTTP 500: <truncated html>") - Sets
structured_content={"status_code": N}so the retry plugin can distinguish retriable (503) from non-retriable (404) errors — matching the existing pattern at line 5040
The original elif status not in [200, 201, 202, 206] branch is retained for non-standard 2xx codes (203, 205, 207).
Test fix
Updated the HTML error response test to actually raise httpx.HTTPStatusError from raise_for_status() instead of mocking it to no-op — the original test passed but didn't exercise the real production code path.
Verification
- 290/290 tests in
test_tool_service.pypass (18 new) - 323/323 tests in
test_tool_service_coverage.pypass - Linters clean (black, isort, eslint)
416641a to
6608f1d
Compare
16579f0 to
d4a4a95
Compare
522cf59 to
b3b72b9
Compare
b3b72b9 to
c529146
Compare
…3857) Backend: - Add _handle_json_parse_error() for graceful fallback when REST APIs return HTML, plain text, XML, or responses with encoding issues - Catch json.JSONDecodeError, orjson.JSONDecodeError, UnicodeDecodeError, and AttributeError during response parsing (httpx uses stdlib json, not orjson) - Add configurable REST_RESPONSE_TEXT_MAX_LENGTH (default: 5000, range: 1000-100000) to truncate non-JSON response text and limit sensitive data exposure - Fix query param handling: GET requests merge URL params with input args (URL params take precedence on conflicts); POST/PUT/PATCH/DELETE preserve query params in URL for signed URL support (Azure SAS, AWS presigned, etc.) - Add jq filter validation to detect email addresses mistakenly used as filters Frontend (admin_ui): - Fix runToolTest/runToolValidation to use tools/call JSON-RPC method instead of tool name as method (MCP protocol compliance) - Add invokeTool() function for "Invoke" button in Tools table - Port all JS changes to modular admin_ui/ structure (Vite bundled) Closes #3855 Closes #3857 Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
…port Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Rakhi Dutta <rakhibiswas@yahoo.com>
Signed-off-by: Brian Hussey <brian.hussey@ie.ibm.com>
7c4bb47 to
a27ee1b
Compare
gcgoncalves
left a comment
There was a problem hiding this comment.
Verified, working fine. 👍
Closes #3855 and #3857
This PR enhances REST tool robustness by improving error handling, query parameter processing, and input validation. It also streamlines the admin UI tool testing workflow.
Backend Improvements
Non-JSON Response Handling (#3855)
Response Truncation (Security Enhancement)
Query Parameter Handling (#3857)
jq Filter Validation
Frontend Enhancements
Admin UI Tool Testing Workflow
{
method: "tools/call",
params: { name: toolName, arguments: {...} }
}
Test Coverage
Comprehensive test suite added: