-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Open
Description
Bug Description
The SDK's HttpClient.request() method calls res.json() without a try/catch in the error-response path. When the server returns a non-JSON error body (HTML 502 gateway page, plain-text 429, Cloudflare challenge page, etc.), res.json() throws a native SyntaxError that bypasses the Context7Error type system.
Affected Code
File: packages/sdk/src/http/index.ts, lines ~171-173
if (!res.ok) {
const errorBody = (await res.json()) as { error?: string; message?: string };
throw new Context7Error(errorBody.error || errorBody.message || res.statusText);
}res.json() is called bare — no try/catch, no Content-Type guard.
Impact
- Any caller using
catch (error) { if (error instanceof Context7Error) ... }will miss the error entirely - Infrastructure errors (Cloudflare 502, AWS ALB 503, rate limiting 429 with HTML body) surface as confusing
SyntaxError: Unexpected token '<' at position 0instead of a typed error with the HTTP status - This affects all SDK consumers: the CLI, the MCP server, and any third-party integration using the SDK
Steps to Reproduce
- Configure Context7 SDK to point to a server that returns a non-JSON error
- (Or simulate: proxy returning HTML 502 on the API endpoint)
- Call any SDK method (e.g.,
resolveLibraryId) - Observe:
SyntaxError: Unexpected token '<'instead ofContext7Error
Proposed Solution
Wrap res.json() in a try/catch:
if (!res.ok) {
const errorBody = await res.json().catch(() => ({})) as { error?: string; message?: string };
throw new Context7Error(errorBody.error || errorBody.message || res.statusText);
}This is a one-line change (adding .catch(() => ({}))) that ensures non-JSON error bodies gracefully fall through to the res.statusText fallback message, and the error is always a typed Context7Error.
Happy to submit a PR for this fix.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels