-
Notifications
You must be signed in to change notification settings - Fork 489
Closed
Description
Bug Description
When MCP server HTTP requests fail (404, 500, etc.), the HTTP API client attempts to parse the error response as JSON without first checking response.ok. This causes a cryptic "Unexpected end of JSON input" error instead of showing the actual server error message.
Impact
- Severity: High - Makes debugging MCP server issues extremely difficult
- User Experience: Users see misleading "JSON parse error" instead of helpful error messages like "Server not found" or actual backend errors
- Affected Operations: All MCP server HTTP operations (add, edit, test, delete)
Affected Code
File: apps/ui/src/lib/http-api-client.ts
Lines: 165-251 (all four HTTP methods: post, get, put, httpDelete)
Current Behavior (Incorrect)
private async post<T>(endpoint: string, body?: unknown): Promise<T> {
const response = await fetch(`${this.serverUrl}${endpoint}`, {
method: 'POST',
headers: this.getHeaders(),
body: body ? JSON.stringify(body) : undefined,
});
return response.json(); // ❌ No error checking - fails with cryptic message
}Example Error:
- Request:
POST /api/mcp/testwith invalid server ID - Response:
404 Not Foundwith body{"error": "Server not found"} - User Sees: "Unexpected end of JSON input" ❌
- Should See: "Server not found" ✅
Expected Behavior
All HTTP methods should validate response.ok before attempting to parse JSON, and provide meaningful error messages.
Proposed Solution
Add response.ok validation to all four HTTP methods with proper error handling:
private async post<T>(endpoint: string, body?: unknown): Promise<T> {
const response = await fetch(`${this.serverUrl}${endpoint}`, {
method: 'POST',
headers: this.getHeaders(),
body: body ? JSON.stringify(body) : undefined,
});
// ✅ Check response status before parsing
if (!response.ok) {
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
try {
const errorData = await response.json();
if (errorData.error) {
errorMessage = errorData.error;
}
} catch {
// If parsing JSON fails, use status text
}
throw new Error(errorMessage);
}
return response.json();
}Apply the same pattern to:
private async get<T>(endpoint: string): Promise<T>private async put<T>(endpoint: string, body?: unknown): Promise<T>private async httpDelete<T>(endpoint: string): Promise<T>
Testing
Before Fix:
- Test invalid MCP server → Shows "Unexpected end of JSON input"
- Test 404 endpoint → Shows "Unexpected end of JSON input"
After Fix:
- Test invalid MCP server → Shows "Server not found"
- Test 404 endpoint → Shows "HTTP 404: Not Found"
- Test 500 error → Shows actual backend error message
Additional Context
- This is a prerequisite fix for proper error visibility in race condition scenarios (see related issue about MCP server auto-test timing)
- No breaking changes - only improves error reporting
- Performance impact: negligible (~1-5ms for error path)
coderabbitai
Metadata
Metadata
Assignees
Labels
No labels