summaryrefslogtreecommitdiffstats
path: root/zellij-tile
diff options
context:
space:
mode:
authorhar7an <99636919+har7an@users.noreply.github.com>2022-10-23 13:14:24 +0000
committerGitHub <noreply@github.com>2022-10-23 13:14:24 +0000
commit75801bdb0e559c73d3f5ea99f1ce1429a425cd1b (patch)
treeabcc1aa1f941f038ef8d328d6ffa79abfc2ff1a9 /zellij-tile
parent788bcd6151431222325800e0a46c58384fe0bd22 (diff)
plugins: Improve error handling on plugin version mismatch (#1838)
* server/tab: Don't panic in `Pane::render` and do not crash the application on failure to receive a render update from plugins any longer. Instead, will print a simple string with a hint to check the application logs, where a more thorough error indication can be found. * utils/errors: re-export `anyhow::Error` to create ad-hoc errors with custom error types, without having to wrap them into a `context()` before to turn the into anyhow errors. * plugins: Check plugin version on startup and terminate execution with a descriptive error message in case the plugin version is incompatible with the version of zellij being run. * server/wasm_vm: Add plugin path in version error so the user knows which plugin to look at in case they're using custom plugins. * server/wasm_vm: Check plugin version for equality Previously we would accept cases where the plugin version was newer than the zellij version, which doesn't make a lot of sense. * server/wasm_vm: Prettier error handling in call to `wasmer::Function::call` in case a plugin version mismatch can occur. * tile: Install custom panic handler that will print the panic message to a plugins stdout and then call a panic handler on the host that turns it into a real application-level panic. * tile: Catch errors in event deserialization and turn them into proper panics. These errors are symptomatic of an uncaught plugin version mismatch, for example when developing from main and compiling zellij/the plugins from source. Normal users should never get to see this error. * utils/errors: Improve output in `to_stdout` for anyhow errors. The default anyhow error formatting of `{:?}` is already very good, and we just made it worse by trying to invent our own formatting. * tile: Reword plugin mismatch error message * zellij: Apply rustfmt * changelog: Add PR #1838 Improve error handling on plugin version mismatch. * server/wasm_vm: Rephrase error in passive voice
Diffstat (limited to 'zellij-tile')
-rw-r--r--zellij-tile/src/lib.rs31
-rw-r--r--zellij-tile/src/prelude.rs2
-rw-r--r--zellij-tile/src/shim.rs17
3 files changed, 44 insertions, 6 deletions
diff --git a/zellij-tile/src/lib.rs b/zellij-tile/src/lib.rs
index 85a5bfe1f..00dc60a96 100644
--- a/zellij-tile/src/lib.rs
+++ b/zellij-tile/src/lib.rs
@@ -10,6 +10,18 @@ pub trait ZellijPlugin {
fn render(&mut self, rows: usize, cols: usize) {}
}
+pub const PLUGIN_MISMATCH: &str =
+ "An error occured in a plugin while receiving an Event from zellij. This means
+that the plugins aren't compatible with the current zellij version.
+
+The most likely explanation for this is that you're running either a
+self-compiled zellij or plugin version. Please make sure that, while developing,
+you also rebuild the plugins in order to pick up changes to the plugin code.
+
+Please refer to the documentation for further information:
+ https://github.com/zellij-org/zellij/blob/main/CONTRIBUTING.md#building
+";
+
#[macro_export]
macro_rules! register_plugin {
($t:ty) => {
@@ -18,6 +30,11 @@ macro_rules! register_plugin {
}
fn main() {
+ // Register custom panic handler
+ std::panic::set_hook(Box::new(|info| {
+ report_panic(info);
+ }));
+
STATE.with(|state| {
state.borrow_mut().load();
});
@@ -25,10 +42,13 @@ macro_rules! register_plugin {
#[no_mangle]
pub fn update() {
+ let object = $crate::shim::object_from_stdin()
+ .context($crate::PLUGIN_MISMATCH)
+ .to_stdout()
+ .unwrap();
+
STATE.with(|state| {
- state
- .borrow_mut()
- .update($crate::shim::object_from_stdin().unwrap());
+ state.borrow_mut().update(object);
});
}
@@ -38,5 +58,10 @@ macro_rules! register_plugin {
state.borrow_mut().render(rows as usize, cols as usize);
});
}
+
+ #[no_mangle]
+ pub fn plugin_version() {
+ println!("{}", $crate::prelude::VERSION);
+ }
};
}
diff --git a/zellij-tile/src/prelude.rs b/zellij-tile/src/prelude.rs
index 819020667..21d1317f6 100644
--- a/zellij-tile/src/prelude.rs
+++ b/zellij-tile/src/prelude.rs
@@ -1,4 +1,6 @@
pub use crate::shim::*;
pub use crate::*;
+pub use zellij_utils::consts::VERSION;
pub use zellij_utils::data::*;
+pub use zellij_utils::errors::prelude::*;
pub use zellij_utils::input::actions;
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index 99920e744..0aa8d3e0e 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -1,6 +1,7 @@
use serde::{de::DeserializeOwned, Serialize};
use std::{io, path::Path};
use zellij_utils::data::*;
+use zellij_utils::errors::prelude::*;
// Subscription Handling
@@ -50,13 +51,22 @@ pub fn exec_cmd(cmd: &[&str]) {
unsafe { host_exec_cmd() };
}
+pub fn report_panic(info: &std::panic::PanicInfo) {
+ println!("");
+ println!("A panic occured in a plugin");
+ println!("{:#?}", info);
+ unsafe { host_report_panic() };
+}
+
// Internal Functions
#[doc(hidden)]
-pub fn object_from_stdin<T: DeserializeOwned>() -> Result<T, serde_json::Error> {
+pub fn object_from_stdin<T: DeserializeOwned>() -> Result<T> {
+ let err_context = || "failed to deserialize object from stdin".to_string();
+
let mut json = String::new();
- io::stdin().read_line(&mut json).unwrap();
- serde_json::from_str(&json)
+ io::stdin().read_line(&mut json).with_context(err_context)?;
+ serde_json::from_str(&json).with_context(err_context)
}
#[doc(hidden)]
@@ -75,4 +85,5 @@ extern "C" {
fn host_switch_tab_to(tab_idx: u32);
fn host_set_timeout(secs: f64);
fn host_exec_cmd();
+ fn host_report_panic();
}