{"record":{"id":"edf7b1018157ee22","repo":"sinelaw/fresh","slug":"js-error-in","errorCode":null,"errorMessage":"JS error in {}: {}: {}","messagePattern":"JS error in (.+?): (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-plugin-runtime/src/backend/quickjs_backend.rs","lineNumber":420,"sourceCode":"            if let Some(exc_obj) = exc.as_object() {\n                let message: String = exc_obj\n                    .get::<_, String>(\"message\")\n                    .unwrap_or_else(|_| \"Unknown error\".to_string());\n                let stack: String = exc_obj.get::<_, String>(\"stack\").unwrap_or_default();\n                let name: String = exc_obj\n                    .get::<_, String>(\"name\")\n                    .unwrap_or_else(|_| \"Error\".to_string());\n\n                if !stack.is_empty() {\n                    return anyhow::anyhow!(\n                        \"JS error in {}: {}: {}\\nStack trace:\\n{}\",\n                        source_name,\n                        name,\n                        message,\n                        stack\n                    );\n                } else {\n                    return anyhow::anyhow!(\"JS error in {}: {}: {}\", source_name, name, message);\n                }\n            } else {\n                // Exception is not an object, try to convert to string\n                let exc_str: String = exc\n                    .as_string()\n                    .and_then(|s: &rquickjs::String| s.to_string().ok())\n                    .unwrap_or_else(|| format!(\"{:?}\", exc));\n                return anyhow::anyhow!(\"JS error in {}: {}\", source_name, exc_str);\n            }\n        }\n    }\n\n    // Fall back to the basic error message\n    anyhow::anyhow!(\"JS error in {}: {}\", source_name, err)\n}\n\n/// Log a JavaScript error with full details\n/// If panic_on_js_errors is enabled, this will panic to surface JS errors immediately","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-plugin-runtime/src/backend/quickjs_backend.rs#L402-L438","documentation":"Formatting step of format_js_error for QuickJS exceptions that are objects: it extracts the error's name, message, and stack from the exception object and builds an anyhow error. This variant fires when a stack trace is absent or empty (e.g. thrown non-Error values like strings/objects lacking `.stack`, or engine errors without trace info); the with-stack variant at the same site is used otherwise. Callers log_js_error and execute_js surface it to the plugin host as the failure reason.","triggerScenarios":"Plugin code throws a value whose 'stack' property is empty/absent (e.g. manually constructed Error without stack, or engine-produced exception lacking stack) during JS execution.","commonSituations":"Throwing plain objects or Errors with stack suppressed in plugins; minified/bundled plugin code stripping stack info; older QuickJS builds not populating stack.","solutions":["Fix the JS error named in the message (e.g. TypeError: undefined is not a function)","Add stack capture by throwing real Error objects in plugin code","Log inputs around the throwing call site to reproduce","Disable code minification for plugin bundles to retain stacks"],"exampleFix":"// before\nthrow 'bad input';\n// after\nthrow new Error('bad input: ' + JSON.stringify(input));","handlingStrategy":"try-catch","validationCode":"// ensure plugin modules only throw Error instances\nfunction assertError(e) { if (!(e instanceof Error)) throw new Error(String(e)); }","typeGuard":null,"tryCatchPattern":"if let Err(e) = backend.execute_js(src) {\n    let msg = e.to_string();\n    if msg.starts_with(\"JS error in\") {\n        eprintln!(\"plugin JS failure (no stack): {msg}\");\n    }\n}","preventionTips":["Always throw Error objects (never strings/numbers) in plugins","Avoid build settings that strip the Error.stack property","Keep runtime and rquickjs versions current","Log plugin inputs to ease reproduction without stacks"],"tags":["javascript","quickjs"],"backgroundTag":"unexpected-response-shape","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}