gildas-lormeau/SingleFile · error · Error
response.error
Error message
response.error
What it means
getJSON first validates the HTTP status via getResponse, then parses the JSON body; if the parsed body contains an `error` property, it throws that value as an Error. This surfaces Google Drive API structured error objects (e.g. {error: {code, message, errors: [...]}}) directly to the caller, so the thrown Error may not be a plain string message.
Source
Thrown at src/lib/gdrive/gdrive.js:477
const range = httpResponse.headers.get("Range");
if (range) {
mediaUploader.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1;
}
if (mediaUploader.cancelled) {
throw new Error("upload_cancelled");
} else {
return sendFile(mediaUploader);
}
} else {
getResponse(httpResponse);
}
}
async function getJSON(httpResponse) {
httpResponse = getResponse(httpResponse);
const response = await httpResponse.json();
if (response.error) {
throw new Error(response.error);
} else {
return response;
}
}
function getResponse(httpResponse) {
if (httpResponse.status == 200) {
return httpResponse;
} else if (httpResponse.status == 404) {
throw new Error("path_not_found");
} else if (httpResponse.status == 401) {
throw new Error("invalid_token");
} else {
throw new Error("unknown_error (" + httpResponse.status + ")");
}
}
View on GitHub (pinned to 517fb7c5cf)
Solutions
- Log/serialize the thrown error's message as JSON (response.error may be an object) to see code, message, and errors[].
- Check the embedded error.errors[].reason for rate limiting and retry with exponential backoff if it is rateLimited/userRateLimitExceeded.
- Verify the OAuth token's scopes cover the requested operation.
- Confirm the endpoint URL and API version are current for the Drive v3 API.
Example fix
// before
catch (e) { console.error(e.message); } // prints [object Object]
// after
catch (e) {
const detail = typeof e.message === "string" ? e.message : JSON.stringify(e.message);
console.error("Drive API error:", detail);
} Defensive patterns
Strategy: type-guard
Type guard
function isDriveErrorPayload(m) {
return m !== null && typeof m === "object" &&
((typeof m.code === "number") || Array.isArray(m.errors) || typeof m.message === "string");
}
// usage
catch (e) { if (isDriveErrorPayload(e.message)) { handleDriveApiError(e.message); } else throw e; } Try / catch
try { const data = await gdrive.getJSON(resp); }
catch (e) {
const payload = typeof e.message === "string" ? { message: e.message } : e.message;
if (payload && payload.errors && payload.errors[0] && payload.errors[0].reason === "rateLimitExceeded") {
return retryWithBackoff();
}
throw e;
} Prevention
- Never assume e.message is a string from this library — normalize it first
- Check error.errors[].reason for Drive-specific retry hints
- Keep Google API usage under quota to avoid body-level errors
When it happens
Trigger: Any call whose HTTP response is 2xx/acceptable but whose JSON body carries an error field — e.g. a Drive API error returned with an unexpected status that getResponse let through, or an endpoint returning 200 with an embedded error object.
Common situations: Drive API rate-limit or userRateLimitExceeded errors wrapped in JSON; malformed OAuth scopes producing an error body; API version changes that move error information into the body; catching the error and assuming message is a string when it is an object.
Related errors
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/506b2ee3fec61fec.
Report an issue: GitHub.