Skip to content

Reject with an HTTPError on non-200 responses - #50

Open
Tyagiquamar wants to merge 1 commit into
serpapi:masterfrom
Tyagiquamar:fix/http-error-on-non-200
Open

Tyagiquamar wants to merge 1 commit into
serpapi:masterfrom
Tyagiquamar:fix/http-error-on-non-200

Conversation

@Tyagiquamar

Copy link
Copy Markdown

Problem

execute() and uploadImage() in src/utils.ts reject with the raw response body string when SerpApi responds with a non-200 status code:

if (resp.statusCode == 200) {
  resolve(data);
} else {
  reject(data); // raw string
}

A rejected bare string is not an Error: it has no HTTP status code, no stack trace, and cannot be distinguished from other failures with instanceof. This makes it hard for callers to branch on the failure kind (for example, a 401 invalid key versus a 429 rate limit) or to log where the rejection came from.

Before:

try {
  const json = await getJson({ engine: "google", api_key: API_KEY, q: "coffee" });
} catch (error) {
  console.log(typeof error); // "string"
  console.log(error instanceof Error); // false
  console.log(error.statusCode); // undefined
}

Solution

Add an HTTPError class in src/errors.ts exposing statusCode and the raw body. The message is set to the error field of a JSON response when present, and falls back to a status-code message for non-JSON bodies. Both request paths now reject with it.

After:

try {
  const json = await getJson({ engine: "google", api_key: API_KEY, q: "coffee" });
} catch (error) {
  if (error instanceof HTTPError) {
    console.log(error.statusCode); // e.g. 401
    console.log(error.body); // e.g. '{"error":"Invalid API key. ..."}'
    console.log(error.message); // e.g. 'Invalid API key. ...'
  }
}

This also matches the structured HTTP errors already exposed by the other SerpApi SDKs: serpapi-python's HTTPError.status_code and serpapi-ruby's SerpApiError#response_status.

Validation

  • New tests/errors_test.ts covers the class for JSON bodies with and without an error field, non-JSON bodies, an empty error field, and an empty body.
  • execute() has a new test in tests/utils_test.ts that hits the real /account endpoint with an invalid API key (no account or paid access required) and asserts the rejection is an HTTPError with statusCode 401 and the message from the JSON error field.
  • The uploadImage stub test now asserts the new error contract.
  • deno fmt --check, deno lint, deno task test, and deno task npm pass.

Notes

  • HTTPError is exported from mod.ts and documented in the README under Configuration.
  • Changelog updated under Unreleased.

execute() and uploadImage() rejected with the raw response body string when
SerpApi returned a non-200 status code. The rejection had no HTTP status code,
was not an Error, and lost the stack trace, so callers could not branch on the
failure kind or log where it came from.

Add an HTTPError class exposing statusCode and the raw body, with the message
set to the error field of a JSON response when present, and reject with it in
both request paths. This matches the structured HTTP errors already exposed by
the serpapi-python (HTTPError.status_code) and serpapi-ruby
(SerpApiError#response_status) SDKs.
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.

1 participant