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
- Check browser devtools Network/Console tab for the underlying JS error (often 'Failed to fetch' = CORS or server down)
- Confirm the server is running and the URL/port is correct
- Add CORS headers on the server (Access-Control-Allow-Origin)
- 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
- Confirm the server is up and the URL/port is right before loading
- Add CORS headers (Access-Control-Allow-Origin) on the asset host
- Check devtools Network tab for 'Failed to fetch' to distinguish CORS from downtime
- Use absolute URLs in deployed builds
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)