sinelaw/fresh · error
JS error in : : Stack trace
Error message
JS error in {}: {}: {}
Stack trace:
{} What it means
format_js_error converts a caught rquickjs exception into a Rust anyhow error. When the exception object exposes a non-empty 'stack' property, the error includes the source name, the JS error name and message, and the full JS stack trace.
Solutions
- Read the stack trace in the error to locate the throwing JS line in your plugin
- Fix the offending JS (undefined function/property, bad arguments, etc.)
- Wrap risky plugin code in try/catch and reject promises explicitly
- Re-run with the updated plugin and confirm the error is gone
Example fix
// before (plugin.js) const cfg = config.settings.timeout; // settings is undefined // after const cfg = config.settings?.timeout ?? 3000;
Defensive patterns
Strategy: try-catch
Validate before calling
// before executing a plugin, lint it for obvious ReferenceErrors/TypeErrors npx eslint --no-eslintrc --env browser plugin.js
Try / catch
match backend.execute_js(src) {
Ok(v) => v,
Err(e) if e.to_string().contains("JS error in") => {
tracing::error!("plugin failed: {e:#}");
// disable plugin or fall back
}
Err(e) => return Err(e),
} Prevention
- Run plugin code through a linter before loading
- Use TypeScript for plugins to catch undefined members at compile time
- Add try/catch around plugin entry points
- Test plugins in isolation before enabling in production
When it happens
Trigger: Plugin JavaScript code throws or has an uncaught exception (TypeError, ReferenceError, user-thrown Error) during execute_js; the exception is captured via the promise rejection tracker or eval and formatted with its stack.
Common situations: Calling an undefined function or property in a plugin; bad arguments to the plugin API; an async plugin callback rejecting; a typo introduced in plugin code after an update.
Related errors
- JS error in
- 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/b41f0026d84b4ff5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-plugin-runtime/src/backend/quickjs_backend.rs:412
source_name: &str,
) -> anyhow::Error {
// Check if this is an exception that we can catch for more details
if err.is_exception() {
// Try to catch the exception to get the full error object
let exc = ctx.catch();
if !exc.is_undefined() && !exc.is_null() {
// Try to get error message and stack from the exception object
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);
}
}View on GitHub (pinned to 67894ca546)