tonhowtf/omniget · error

subtitle_save error surfaced to user via err() (localized…

Error message

subtitle_save error surfaced to user via err() (localized toast)

What it means

The Tauri backend command `subtitle_save` failed while persisting subtitle cues to the path chosen via saveAs. The component intentionally rethrows the backend error to the user via the shared err() helper, which shows a localized toast instead of a success message.

Solutions

  1. Check the toast/backend message for the concrete cause (path vs format vs serialization)
  2. Verify the target directory is writable and the path is valid for the OS
  3. Confirm the format value matches a backend-supported subtitle format
  4. Retry the save with a different location/filename

Example fix

// before
catch (e) {
  err(e);
}
// after
catch (e) {
  err(e);
  showToast("error", $t("downloads.sw.save_failed_hint") as string);
  console.warn("subtitle_save failed", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!path || typeof path !== "string" || path.trim() === "") return;
if (!cues?.length) return;

Type guard

function isValidPath(p: unknown): p is string {
  return typeof p === "string" && p.trim().length > 0;
}

Try / catch

try {
  await invoke("subtitle_save", { path, cues, format });
  showToast("success", $t("downloads.sw.saved") as string);
} catch (e) {
  const msg = typeof e === "string" ? e : (e as Error)?.message ?? String(e);
  err(msg);
  showToast("error", $t("downloads.sw.save_failed") as string);
}

Prevention

When it happens

Trigger: invoke("subtitle_save", { path, cues, format }) rejects: unwritable/invalid path, unsupported format string, backend serialization failure on cues, or filesystem permission errors on save.

Common situations: Saving to a read-only or cloud-synced directory, invalid characters in filename, backend command renamed/changed signature after an app update, or cues containing data the serializer cannot encode.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/5a87827d277b2e61. Report an issue: GitHub.

Appendix: source

Thrown at src/components/downloads/SubtitleWorkshop.svelte:259

    const b = na - a * oa;
    cues = cues.map((c) => ({
      ...c,
      start_ms: Math.max(0, Math.round(a * c.start_ms + b)),
      end_ms: Math.max(0, Math.round(a * c.end_ms + b)),
    }));
  }

  async function saveAs(format: "srt" | "vtt" | "ass") {
    if (!cues.length) return;
    const path = await saveDialog({
      filters: [{ name: format.toUpperCase(), extensions: [format] }],
    });
    if (!path) return;
    try {
      await invoke("subtitle_save", { path, cues, format });
      showToast("success", $t("downloads.sw.saved") as string);
    } catch (e) {
      err(e);
    }
  }
</script>

<div
  class="overlay"
  role="button"
  tabindex="0"
  onclick={(e) => { if (e.target === e.currentTarget) onClose(); }}
  onkeydown={(e) => { if (e.key === "Escape") onClose(); }}
>
  <div class="panel" role="dialog" aria-modal="true" aria-label={$t('downloads.sw.title') as string}>
    <div class="head">
      <h2>{$t('downloads.sw.title')}</h2>
      <button class="x" onclick={onClose} aria-label={$t('common.close') as string}>✕</button>
    </div>

    <div class="toolbar">

View on GitHub (pinned to 8600b91f42)