a-b-street/abstreet · error · anyhow::Error

{:?}

Error message

{:?}

What it means

The same FileLoader also formats raw fetch failures as '{:?}' — the JS error value returned by the fetch promise's Err branch, debug-printed into an anyhow error. This covers network-level failures before an HTTP status exists: DNS failure, connection refused, CORS blocks (browser yields a TypeError), or aborts.

Solutions

  1. Check browser devtools Network/Console tab for the underlying JS error (often 'Failed to fetch' = CORS or server down)
  2. Confirm the server is running and the URL/port is correct
  3. Add CORS headers on the server (Access-Control-Allow-Origin)
  4. Verify the URL is absolute and valid for the browser context

Example fix

// before: relative path that may not resolve from the page origin
tx.send(load("data/map.bin"));
// after: absolute URL on a CORS-enabled server
tx.send(load("http://localhost:8000/data/map.bin"));
Defensive patterns

Strategy: retry

Validate before calling

function reachable(url: string): Promise<boolean> {
  return fetch(url, { method: 'HEAD' }).then(() => true).catch(() => false);
}

Try / catch

match file_loader.response.recv() {
    Ok(Ok(bytes)) => use(bytes),
    Ok(Err(e)) => retry_with_backoff(3, || load(url)),
    Err(_) => show_error("loader closed"),
}

Prevention

When it happens

Trigger: The wasm fetch promise rejects: network is offline, server unreachable, CORS preflight blocked, invalid URL causing a JS TypeError, or the request was aborted.

Common situations: Developing against a local server that isn't running, wrong port/hostname, missing CORS headers when the page origin differs from the file host, typo in the URL scheme.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/b2c56c9a9391accc. Report an issue: GitHub.

Appendix: source

Thrown at widgetry/src/tools/load.rs:195

                            while let Some(Ok(chunk)) = stream.next().await {
                                let array = js_sys::Uint8Array::new(&chunk);
                                if let Err(err) =
                                    tx_read_bytes.try_send(array.byte_length() as usize)
                                {
                                    warn!("Couldn't send update on bytes: {}", err);
                                }
                                // TODO Can we avoid this clone?
                                buffer.extend(array.to_vec());
                            }
                            tx.send(Ok(buffer)).unwrap();
                        } else {
                            let status = resp.status();
                            let err = resp.status_text();
                            tx.send(Err(anyhow!("HTTP {}: {}", status, err))).unwrap();
                        }
                    }
                    Err(err) => {
                        tx.send(Err(anyhow!("{:?}", err))).unwrap();
                    }
                }
            });

            Box::new(FileLoader {
                response: rx,
                on_load: Some(on_load),
                panel: ctx.make_loading_screen(Text::from(format!("Loading {}...", url))),
                started: Instant::now(),
                url,
                total_bytes: None,
                read_bytes: 0,
                got_total_bytes,
                got_read_bytes,
            })
        }
    }

View on GitHub (pinned to 0964f29315)