redis/node-redis · error · Error
HTTP ${response.status} - ${text}
Error message
HTTP ${response.status} - ${text} What it means
Intended to be thrown by #request when the fault-injector HTTP response is not ok AND the body text could be read, embedding the body for diagnostics. HOWEVER this throw lives INSIDE the try block whose catch (next line) throws error 113, so the throw here is always caught and error 112 is effectively masked — callers never receive it. The body text is lost. This is a bug: the throw should be moved outside the try.
Source
Thrown at packages/test-utils/lib/fault-injector/fault-injector-client.ts:224
// Add timeout to fetch using AbortController
const controller = new AbortController();
const timeoutId = globalThis.setTimeout(() => {
controller.abort();
}, timeoutMs);
try {
const response = await this.#fetch(url, {
method,
headers,
body: payload,
signal: controller.signal
});
if (!response.ok) {
try {
const text = await response.text();
throw new Error(`HTTP ${response.status} - ${text}`);
} catch {
throw new Error(`HTTP ${response.status}`);
}
}
try {
const result = (await response.json()) as T;
return result;
} catch {
throw new Error(
`HTTP ${response.status} - Unable to parse response as JSON`
);
}
} finally {
globalThis.clearTimeout(timeoutId);
}
}
View on GitHub (pinned to 90fd0652bc)
Solutions
- Patch #request so the throw is outside the try: read text in the try, throw after it
- Until patched, reproduce the request manually (curl) to see the body the library discards
- Pass a custom fetchImpl to the FaultInjectorClient that logs response bodies for debugging
Example fix
// before — throw inside try is swallowed by catch (bug)
if (!response.ok) {
try {
const text = await response.text();
throw new Error(`HTTP ${response.status} - ${text}`);
} catch {
throw new Error(`HTTP ${response.status}`);
}
}
// after — read in try, throw outside
if (!response.ok) {
let text: string | undefined;
try { text = await response.text(); } catch { /* ignore */ }
throw new Error(text ? `HTTP ${response.status} - ${text}` : `HTTP ${response.status}`);
} Defensive patterns
Strategy: try-catch
Try / catch
try {
await fi.listActions();
} catch (e) {
if (e instanceof Error && /HTTP \d{3}/.test(e.message)) {
}
throw e;
} Prevention
- Patch #request so the body-including throw is not caught by its own catch (move throw outside try)
- Until patched, reproduce failing requests with curl to read the hidden body
- Inject a logging fetchImpl into FaultInjectorClient to capture response bodies during debugging
When it happens
Trigger: Any non-ok HTTP response from the fault-injector REST API where response.text() resolves. Due to the catch bug, the caller receives error 113 ('HTTP <status>') without the body instead.
Common situations: 4xx/5xx from the fault-injector service (bad parameters, not found, server error); the developer sees error 113 and loses the explanatory body text, making diagnosis harder.
Related errors
- HTTP ${response.status}
- Action id: ${actionId} failed! Error: ${action.error}
- HTTP ${response.status} - Unable to parse response as JSON
- Timeout waiting for action ${actionId}
- No endpoints found in database config
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/5abb067c81fa5bdc.
Report an issue: GitHub.