amir20/dozzle · error · Error

Preview failed

Error message

Preview failed

What it means

validatePreview() POSTs the alert expression to the preview endpoint to see which containers would match before saving. If the response is not ok, it throws "Preview failed", or the server's error field if provided. Unlike saveAlert, it is called from inside the form flow, so a throw here surfaces as an unhandled rejection unless the caller catches it.

Solutions

  1. Check the server error text (errData.error) — for regex/expression failures it names the invalid syntax; correct the expression before previewing.
  2. Validate the expression client-side before calling: compile the regex or expression and bail out early on parse failure.
  3. Confirm the preview API route exists and the request URL/base path is correct (a 404 here usually means a proxy or version mismatch).
  4. Wrap the preview call in try/catch and show the message in the form instead of letting it throw.

Example fix

// before
await validatePreview(); // unhandled throw on bad regex
// after
if (containerExpression.value) {
  try { new RegExp(logExpression.value); } catch (e) {
    previewError.value = "Invalid regex: " + e.message;
    return;
  }
  await validatePreview();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate expression before preview
let regexOk = true;
try { new RegExp(logExpression.value); } catch { regexOk = false; }
if (!regexOk) return; // skip validatePreview

Try / catch

try {
  await validatePreview();
} catch (e) {
  previewError.value = e instanceof Error ? e.message : "Preview failed";
}

Prevention

When it happens

Trigger: Calling validatePreview() with a containerExpression or log query the preview endpoint rejects with a non-2xx status: invalid regex, malformed expression syntax, missing required fields in extraFields, or a 500 from the backend while evaluating the expression against containers.

Common situations: Typing an invalid regex pattern into the expression box and hitting preview; previewing before any containers are selected; backend errors because the preview route is unavailable (proxy misconfiguration or older backend without the preview endpoint returning 404).

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


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/fe5a1da39e224ff4. Report an issue: GitHub.

Appendix: source

Thrown at assets/composable/alertForm.ts:132

  async function validatePreview(extraFields: Record<string, unknown> = {}) {
    if (!containerExpression.value && !Object.values(extraFields).some(Boolean)) {
      containerResult.value = null;
      return { data: null };
    }

    isLoading.value = true;
    try {
      const res = await fetch(withBase("/api/notifications/preview"), {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          containerExpression: containerExpression.value,
          ...extraFields,
        }),
      });
      if (!res.ok) {
        const errData = await res.json();
        throw new Error(errData.error || "Preview failed");
      }
      const data: PreviewResult = await res.json();
      containerResult.value = containerExpression.value
        ? {
            error: data.containerError ?? undefined,
            containers: data.matchedContainers?.map((c) => Container.fromJSON(c as ContainerJson)),
          }
        : null;
      return { data };
    } catch (e) {
      containerResult.value = { error: e instanceof Error ? e.message : "Unknown error" };
      return { data: null };
    } finally {
      isLoading.value = false;
    }
  }

  return {

View on GitHub (pinned to d9463cbe21)