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

no local_storage?

Error message

no local_storage?

What it means

read_local_storage expects window.local_storage() to return Some(Storage); a None means the browser gave no storage object for this origin. The library turns that into the "no local_storage?" error. This is separate from a failed call or a missing key.

Solutions

  1. Treat localStorage as optional: fall back to in-memory or IndexedDB storage
  2. Detect the condition up front with web_sys::window().and_then(|w| w.local_storage().ok().flatten()) before using the library API
  3. Enable storage for the webview/origin in the embedding application
  4. Inform the user that saving requires enabling site data

Example fix

// before
let raw = abstio::slurp_file(path).expect("storage");
// after
let has_storage = web_sys::window()
    .and_then(|w| w.local_storage().ok().flatten())
    .is_some();
let raw = if has_storage { abstio::slurp_file(path)? } else { default_value() };
Defensive patterns

Strategy: fallback

Validate before calling

let has_storage = web_sys::window()
    .and_then(|w| w.local_storage().ok().flatten())
    .is_some();

Type guard

fn local_storage_available() -> bool {
    web_sys::window().and_then(|w| w.local_storage().ok().flatten()).is_some()
}

Try / catch

let raw = if local_storage_available() {
    slurp_file(path).unwrap_or_default()
} else {
    in_memory_store().get(path).cloned().unwrap_or_default()
};

Prevention

When it happens

Trigger: Calling read_local_storage (via slurp_file/maybe_read_binary) in a context where window.local_storage() resolves to None — e.g. storage disabled for the origin, certain privacy modes, or insecure/embedded contexts where the browser suppresses localStorage.

Common situations: Safari older private-browsing sessions where localStorage appears absent; embedded webviews with WebStorage disabled; origins with storage partitioned away.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at abstio/src/io_web.rs:174

    if !path.starts_with(&path_player("")) {
        warn!("Not deleting {}", path);
        return;
    }
    let window = web_sys::window().unwrap();
    let storage = window.local_storage().unwrap().unwrap();
    storage.remove_item(path).unwrap();
}

fn read_local_storage(path: &str) -> Result<String> {
    let window = web_sys::window().ok_or(anyhow!("no window?"))?;
    let storage = window
        .local_storage()
        .map_err(|err| {
            anyhow!(err
                .as_string()
                .unwrap_or("local_storage failed".to_string()))
        })?
        .ok_or(anyhow!("no local_storage?"))?;
    let string = storage
        .get_item(&path)
        .map_err(|err| anyhow!(err.as_string().unwrap_or("get_item failed".to_string())))?
        .ok_or(anyhow!("{} missing from local storage", path))?;
    Ok(string)
}

fn list_local_storage_keys() -> Vec<String> {
    let window = web_sys::window().unwrap();
    let storage = window.local_storage().unwrap().unwrap();
    let mut keys = Vec::new();
    for idx in 0..storage.length().unwrap() {
        keys.push(storage.key(idx).unwrap().unwrap());
    }
    keys
}

/// Returns path on success

View on GitHub (pinned to 0964f29315)