{"record":{"id":"54da5c611554005b","repo":"a-b-street/abstreet","slug":"http","errorCode":null,"errorMessage":"HTTP {}: {}","messagePattern":"HTTP (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"widgetry/src/tools/load.rs","lineNumber":191,"sourceCode":"                            let raw_body = resp.body().unwrap_throw();\n                            let body = ReadableStream::from_raw(raw_body.dyn_into().unwrap_throw());\n                            let mut stream = body.into_stream();\n                            let mut buffer = Vec::new();\n                            while let Some(Ok(chunk)) = stream.next().await {\n                                let array = js_sys::Uint8Array::new(&chunk);\n                                if let Err(err) =\n                                    tx_read_bytes.try_send(array.byte_length() as usize)\n                                {\n                                    warn!(\"Couldn't send update on bytes: {}\", err);\n                                }\n                                // TODO Can we avoid this clone?\n                                buffer.extend(array.to_vec());\n                            }\n                            tx.send(Ok(buffer)).unwrap();\n                        } else {\n                            let status = resp.status();\n                            let err = resp.status_text();\n                            tx.send(Err(anyhow!(\"HTTP {}: {}\", status, err))).unwrap();\n                        }\n                    }\n                    Err(err) => {\n                        tx.send(Err(anyhow!(\"{:?}\", err))).unwrap();\n                    }\n                }\n            });\n\n            Box::new(FileLoader {\n                response: rx,\n                on_load: Some(on_load),\n                panel: ctx.make_loading_screen(Text::from(format!(\"Loading {}...\", url))),\n                started: Instant::now(),\n                url,\n                total_bytes: None,\n                read_bytes: 0,\n                got_total_bytes,\n                got_read_bytes,","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/tools/load.rs#L173-L209","documentation":"FileLoader fetches a remote file over HTTP in the browser and sends the downloaded bytes over a channel. When the fetch response's status is not OK (resp.ok() false), it formats 'HTTP <status>: <status_text>' and sends that as the error. It surfaces any non-2xx HTTP response from the server hosting the file.","triggerScenarios":"Calling the load/new_state API with a URL that the server answers with a non-2xx status: 404 for a missing file, 403 for permissions, 500 for a server error, CORS-related 4xx, or a redirect that ends in an error page.","commonSituations":"Wrong or misspelled URL/path for the data file, file not deployed to the web server, missing CORS headers causing the browser to reject the response, server misconfiguration.","solutions":["Verify the URL is correct and the file is reachable (curl -I the URL)","Check server logs for the status code's cause","Fix CORS headers (Access-Control-Allow-Origin) if the browser is blocking the response","Serve the file from the correct location or redeploy the asset"],"exampleFix":"// before\nlet url = \"data/scenarios/map.bin\";\n// after: full, verified URL\nlet url = \"https://example.com/abst/data/scenarios/map.bin\";","handlingStrategy":"validation","validationCode":"// before loading, verify reachability and permissions\nlet resp = reqwest::blocking::head(url).send()?;\nif !resp.status().is_success() {\n    bail!(\"asset {} not available: {}\", url, resp.status());\n}","typeGuard":"function is_ok_response(resp: Response): boolean { return resp.ok; }","tryCatchPattern":"match file_loader.response.recv() {\n    Ok(Ok(bytes)) => use(bytes),\n    Ok(Err(e)) => show_error(format!(\"Could not load file: {} — check the URL and server\", e)),\n    Err(_) => show_error(\"loader channel closed\"),\n}","preventionTips":["Verify asset URLs with curl -I before deploying","Deploy all data files alongside the app and keep paths consistent","Configure CORS headers on the asset server","Monitor server logs for 404/403 on asset requests"],"tags":["http","network","fetch","browser"],"backgroundTag":"http-error-response","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}