sinelaw/fresh · error
JS error in
Error message
JS error in {}: {}: {} What it means
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.
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
Example fix
// before
throw 'bad input';
// after
throw new Error('bad input: ' + JSON.stringify(input)); Defensive patterns
Strategy: try-catch
Validate before calling
// ensure plugin modules only throw Error instances
function assertError(e) { if (!(e instanceof Error)) throw new Error(String(e)); } Try / catch
if let Err(e) = backend.execute_js(src) {
let msg = e.to_string();
if msg.starts_with("JS error in") {
eprintln!("plugin JS failure (no stack): {msg}");
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Throwing plain objects or Errors with stack suppressed in plugins; minified/bundled plugin code stripping stack info; older QuickJS builds not populating stack.
Related errors
- JS error in : : Stack trace
- JS error in
- editor.spawnProcess is not implemented (missing…
- editor.spawnHostProcess is not implemented (missing…
- Cannot resolve import
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/edf7b1018157ee22.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-plugin-runtime/src/backend/quickjs_backend.rs:420
if let Some(exc_obj) = exc.as_object() {
let message: String = exc_obj
.get::<_, String>("message")
.unwrap_or_else(|_| "Unknown error".to_string());
let stack: String = exc_obj.get::<_, String>("stack").unwrap_or_default();
let name: String = exc_obj
.get::<_, String>("name")
.unwrap_or_else(|_| "Error".to_string());
if !stack.is_empty() {
return anyhow::anyhow!(
"JS error in {}: {}: {}\nStack trace:\n{}",
source_name,
name,
message,
stack
);
} else {
return anyhow::anyhow!("JS error in {}: {}: {}", source_name, name, message);
}
} else {
// Exception is not an object, try to convert to string
let exc_str: String = exc
.as_string()
.and_then(|s: &rquickjs::String| s.to_string().ok())
.unwrap_or_else(|| format!("{:?}", exc));
return anyhow::anyhow!("JS error in {}: {}", source_name, exc_str);
}
}
}
// Fall back to the basic error message
anyhow::anyhow!("JS error in {}: {}", source_name, err)
}
/// Log a JavaScript error with full details
/// If panic_on_js_errors is enabled, this will panic to surface JS errors immediatelyView on GitHub (pinned to 67894ca546)