Skip to content

Commit aa38de7

Browse files
committed
fix(cli): override rolldown panic hook with vite-plus branding
Since rolldown_binding is bundled into the same NAPI binary, its module_init panic hook catches all panics and misleadingly shows "Rolldown panicked" with a link to rolldown's issue tracker. Replace it at the start of run() with a vite-plus specific hook that correctly attributes panics and links to the vite-plus bug report. Closes #1285
1 parent f1f6016 commit aa38de7

File tree

1 file changed

+24
-0
lines changed
  • packages/cli/binding/src

1 file changed

+24
-0
lines changed

packages/cli/binding/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,37 @@ fn format_error_message(error: &(dyn StdError + 'static)) -> String {
123123
message
124124
}
125125

126+
/// Override rolldown's panic hook with a vite-plus specific one.
127+
///
128+
/// rolldown_binding sets a global panic hook in its `#[module_init]` that prints
129+
/// "Rolldown panicked" for ALL panics. Since vite-plus bundles rolldown into the
130+
/// same binary, we need to replace it so panics are correctly attributed to Vite+.
131+
#[allow(clippy::disallowed_macros)]
132+
fn setup_panic_hook() {
133+
static ONCE: std::sync::Once = std::sync::Once::new();
134+
ONCE.call_once(|| {
135+
// First take_hook discards rolldown's custom hook (which wraps the default
136+
// in a closure that prints "Rolldown panicked"). Second gets the real default.
137+
let _ = std::panic::take_hook();
138+
let default_hook = std::panic::take_hook();
139+
std::panic::set_hook(Box::new(move |info| {
140+
eprintln!("Vite+ panicked. This is a bug in Vite+, not your code.\n");
141+
default_hook(info);
142+
eprintln!(
143+
"\nPlease report this issue at: https://github.com/voidzero-dev/vite-plus/issues/new?template=bug_report.yml"
144+
);
145+
}));
146+
});
147+
}
148+
126149
/// Main entry point for the CLI, called from JavaScript.
127150
///
128151
/// This is an async function that spawns a new thread for the non-Send async code
129152
/// from vite_task, while allowing the NAPI async context to continue running
130153
/// and process JavaScript callbacks (via ThreadsafeFunction).
131154
#[napi]
132155
pub async fn run(options: CliOptions) -> Result<i32> {
156+
setup_panic_hook();
133157
// Use provided cwd or current directory
134158
let mut cwd = current_dir()?;
135159
if let Some(options_cwd) = options.cwd {

0 commit comments

Comments
 (0)