amir20/dozzle · error · Error
response.statusText
Error message
response.statusText
What it means
ContainerActionsToolbar.vue downloads a text blob (e.g. container logs export) via fetch. If the HTTP response is not ok (status outside 200-299), it throws a plain Error carrying only response.statusText. Because statusText is often empty in HTTP/2 responses, the resulting error message can be blank, making the failure hard to diagnose.
Solutions
- Check the network tab for the actual status code and response body of the failed request
- Re-authenticate or refresh the page if the status is 401/403
- Verify the container still exists and the host is reachable before retrying the download
- Improve the error to include response.status since statusText may be empty on HTTP/2
Example fix
// before
if (!response.ok) throw new Error(response.statusText);
// after
if (!response.ok) throw new Error(`Download failed: ${response.status} ${response.statusText || "request rejected"}`); Defensive patterns
Strategy: try-catch
Validate before calling
// before downloading
if (!navigator.onLine) throw new Error("offline");
const res = await fetch(url, { method: "HEAD", headers: { Accept: "text/plain" } });
if (!res.ok) throw new Error(`Download unavailable: ${res.status}`); Try / catch
try {
await downloadLogs(url);
} catch (e) {
showToast({ type: "error", message: e instanceof Error && e.message ? e.message : t("error.something-went-wrong") });
} Prevention
- Include response.status in thrown messages since statusText is empty on HTTP/2
- Check container/host liveness before triggering downloads
- Handle 401 by redirecting to login instead of showing a generic toast
When it happens
Trigger: Clicking a download action in the container toolbar while the fetch to `url` (typically /api/hosts/{host}/containers/{id}/logs/download or similar) returns a non-2xx status: container stopped/removed mid-download, auth token expired, reverse proxy returning 502/504, or the endpoint route missing.
Common situations: Session expired so the API returns 401; a proxy (nginx/Traefik) intercepts and returns 502; Docker daemon briefly unavailable so backend returns 500; user on HTTP/2 where statusText is the empty string, so the toast shows 'Error' with no detail.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Failed to fetch logs
- No reader available from stream
- (await res.json().catch(() =>
- (await res.json().catch(() =>
- Failed to save alert
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/9660984fda7b2aab.
Report an issue: GitHub.
Appendix: source
Thrown at assets/components/ContainerViewer/ContainerActionsToolbar.vue:367
selectedLevels.forEach((level) => params.append("levels", level));
}
const url = withBase(`/api/hosts/${container.host}/containers/${container.id}/logs?${params.toString()}`);
const toastId = "copy-logs";
showToast(
{
id: toastId,
title: t("toolbar.copying-logs"),
message: "",
type: "info",
},
{ once: true },
);
const blobPromise = fetch(url, { headers: { Accept: "text/plain" } })
.then((response) => {
if (!response.ok) throw new Error(response.statusText);
return response.blob();
})
.then((blob) => {
removeToast(toastId);
showToast(
{
title: t("toasts.copied.title"),
message: t("toasts.copied.message"),
type: "info",
},
{ expire: 2000 },
);
return blob;
})
.catch((err) => {
removeToast(toastId);
showToast(
{View on GitHub (pinned to d9463cbe21)