{"record":{"id":"d990726001621a2d","repo":"BigPizzaV3/CodexPlusPlus","slug":"throw-new-error","errorCode":null,"errorMessage":"throw new Error({});","messagePattern":"throw new Error\\((.+?)\\);","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/codex-plus-core/src/user_scripts.rs","lineNumber":246,"sourceCode":"            \"enabled\": config.enabled,\n            \"builtin_dir\": self.builtin_dir.to_string_lossy(),\n            \"user_dir\": self.user_dir.to_string_lossy(),\n            \"scripts\": scripts\n        }))\n    }\n\n    pub fn build_enabled_bundle(&self) -> anyhow::Result<String> {\n        let config = self.load_config();\n        if !config.enabled {\n            return Ok(String::new());\n        }\n        let mut blocks = Vec::new();\n        for script in self.scan_script_files(&config)? {\n            if !script.enabled {\n                continue;\n            }\n            let source = fs::read_to_string(&script.path)\n                .unwrap_or_else(|error| format!(\"throw new Error({});\", json!(error.to_string())));\n            blocks.push(wrap_script(&script, &source));\n        }\n        Ok(blocks.join(\"\\n\"))\n    }\n\n    fn scan_scripts(\n        &self,\n        config: &UserScriptConfig,\n        runtime_status: Option<&Value>,\n    ) -> anyhow::Result<Vec<Value>> {\n        let runtime_scripts = runtime_status\n            .and_then(|value| value.get(\"scripts\").or(Some(value)))\n            .and_then(Value::as_object);\n        Ok(self\n            .scan_script_files(config)?\n            .into_iter()\n            .map(|script| {\n                let market = config.market.get(&script.key);","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/user_scripts.rs#L228-L264","documentation":"In codex-plus-core's build_enabled_bundle, each enabled user script file is read with fs::read_to_string. If reading a script file fails (missing file, permission denied, invalid UTF-8, IO error), the reader does not abort the bundle build; instead it substitutes a JavaScript stub `throw new Error(\"...\");` as the script body, embedding the Rust IO error message. This means the generated bundle will raise this error in the JS runtime whenever that script executes, surfacing the file-read failure at script-run time rather than bundle-build time.","triggerScenarios":"Calling build_enabled_bundle (via the apply/scan script pipeline) while an enabled script's path no longer exists, is unreadable due to permissions, or contains invalid UTF-8 bytes.","commonSituations":"User deleted or renamed a script file but left it marked enabled in the scripts config; scripts directory moved or synced incompletely between machines; a symlink pointing to a removed target; a non-UTF8 (e.g. UTF-16 or GBK) script file saved by a Windows editor.","solutions":["Locate the failing script from the embedded error message and either recreate the file at its configured path or disable/remove it from the script list.","Re-save the script file as UTF-8 (read_to_string fails on invalid UTF-8).","Fix file permissions on the script file so the process user can read it.","If you want build-time detection instead of runtime throws, change the code to fail the scan (propagate the io::Error with `?`) or log a warning and skip disabled/broken scripts."],"exampleFix":"// before: silent stub that throws at script runtime\nlet source = fs::read_to_string(&script.path)\n    .unwrap_or_else(|error| format!(\"throw new Error({});\", json!(error.to_string())));\n// after: propagate the failure at bundle-build time\nlet source = fs::read_to_string(&script.path)\n    .map_err(|error| anyhow!(\"failed to read script {:?}: {}\", script.path, error))?;","handlingStrategy":"validation","validationCode":"for script in &scripts {\n    if script.enabled && !script.path.exists() {\n        eprintln!(\"warning: enabled script missing: {:?}\", script.path);\n    }\n    if script.enabled && !script.path.is_file() {\n        // exclude from bundle or fail fast\n    }\n}","typeGuard":"fn readable_utf8_script(path: &Path) -> bool {\n    path.is_file() && fs::read(path).map(|bytes| std::str::from_utf8(&bytes).is_ok()).unwrap_or(false)\n}","tryCatchPattern":"// Rust has no try/catch; wrap the bundle build and surface the substituted runtime error\nmatch build_enabled_bundle(&config) {\n    Ok(bundle) => install(bundle),\n    Err(e) => eprintln!(\"脚本包构建失败: {e}\"),\n}\n// at runtime, catch the injected throw\ntry { runUserScript(source); } catch (e) { console.error(\"脚本文件读取失败:\", e.message); }","preventionTips":["Disable or delete script entries in the config as soon as the underlying file is removed.","Save scripts as UTF-8 without BOM; avoid editors that write UTF-16.","Keep script files inside the project/user directory; avoid fragile symlinked locations.","Run a script-directory health check (exists + readable) before applying the bundle."],"tags":["file-read","rust","io","user-scripts"],"backgroundTag":"file-read-failed","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}