tonhowtf/omniget · error · anyhow::Error

worker task panicked

Error message

worker task panicked: {:?}

What it means

download_chunked spawns per-segment worker tasks and joins them; if a worker task itself panicked (rather than returning Err), the JoinHandle resolves with a JoinError. The fetcher wraps that panic in an anyhow error carrying the panic payload, cancels all other segments, and aborts the download. It signals a bug or abort inside worker code, not a network failure.

Solutions

  1. Reproduce with the panic payload from `{:?}` (it names the panic message and source location) and fix the panicking code in worker_loop/download_segment.
  2. Check byte-offset arithmetic against very large files (>4 GiB) and zero-length ranges; replace unwrap/expect with proper error returns.
  3. If the JoinError is a cancellation, audit who is aborting tasks and ensure shutdown is graceful rather than via abort().
  4. Wrap worker bodies with a catch_unwind or ensure all failure paths return Result so errors flow through first_err instead of panicking.

Example fix

// before
let end = range_start + chunk_size; // can overflow/panic downstream
// after
let end = range_start.saturating_add(chunk_size).min(total_len - 1);
Defensive patterns

Strategy: try-catch

Type guard

// Rust: inspect JoinError before trusting the payload
fn is_panic(je: &tokio::task::JoinError) -> bool { je.is_panic() }

Try / catch

match download(...).await {
    Err(e) if e.to_string().starts_with("worker task panicked") => {
        // bug in worker code: log payload, file a fix, restart download
    }
    Err(e) => { /* normal network failure path */ }
    Ok(v) => { /* proceed */ }
}

Prevention

When it happens

Trigger: A tokio worker task spawned by download_chunked panics — e.g. a slice index out of bounds on a segment range, unwrap() on a None state, or an explicit panic!/assertion inside worker_loop/download_segment — and the .join() future resolves to Err(JoinError).

Common situations: Panic on unusual Content-Range responses (negative/overflowing byte offsets), bugs in retry-state bookkeeping, or task aborts surfacing as JoinError::is_cancelled after a runtime shutdown.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/http_fetcher.rs:545

            let cfg = self.config.clone();
            tasks.push(tokio::spawn(async move {
                worker_loop(client, url, headers, part_path, segments, cancel, cfg).await
            }));
        }

        let mut first_err: Option<anyhow::Error> = None;
        for t in tasks {
            match t.await {
                Ok(Ok(())) => {}
                Ok(Err(e)) => {
                    if first_err.is_none() {
                        first_err = Some(e);
                    }
                    cancel.cancel();
                }
                Err(e) => {
                    if first_err.is_none() {
                        first_err = Some(anyhow!("worker task panicked: {:?}", e));
                    }
                    cancel.cancel();
                }
            }
        }

        progress_pump.abort();
        if let Some(p) = resume_pump {
            p.abort();
        }
        let _ = progress_pump.await;

        if let Some(e) = first_err {
            return Err(e);
        }

        let segs = segments.lock().await;
        let all_done = segs

View on GitHub (pinned to 8600b91f42)