macro_rules! event_handler_body {
(
$env:ident, $handler:ident, $event_container:expr, $function_js_name:literal, $function_rust_name:ident($event_type:ty)
) => {
let extension_context = crate::vscode_sys::VscodeContext::extension_context($env)?;
let mut subscriptions: bindgen_prelude::Array =
extension_context.get_named_property("subscriptions")?;
let event_creator: bindgen_prelude::Function<
bindgen_prelude::Function<$event_type, ()>,
bindgen_prelude::Object,
> = $event_container.get_named_property($function_js_name)?;
let event_handler_fn: bindgen_prelude::Function<$event_type, ()> = $env
.create_function_from_closure($function_js_name, move |function_context| {
let parent_span = tracing::span!(tracing::Level::TRACE, "event_handler");
let _entered_span = parent_span.enter();
let event = match function_context.args::<($event_type,)>() {
Ok((event,)) => event,
Err(error) => {
tracing::error!(
message = "Invalid arguments provided to event handler",
event_handler = $function_js_name,
?error
);
return Err(napi::Error::from_reason(
"Invalid arguments provided to event handler",
));
}
};
match std::panic::catch_unwind(|| $handler(function_context.env, event)) {
Ok(handler_result) => match handler_result {
Ok(result) => Ok(result),
Err(error) => {
tracing::error!(
message = "Event handler returned an error",
event_handler = $function_js_name,
?error
);
Err(napi::Error::from_reason("Event handler returned an error"))
}
},
Err(panic_payload) => {
tracing::error!(
message = "Event handler panicked",
event_handler = $function_js_name,
?panic_payload
);
Err(napi::Error::from_reason("Event handler panicked"))
}
}
})?;
let handler_subscription: bindgen_prelude::Object = event_creator.call(event_handler_fn)?;
subscriptions.insert(handler_subscription)?;
Ok(())
};
}
pub(crate) use event_handler_body;