summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhar7an <99636919+har7an@users.noreply.github.com>2022-10-28 17:12:05 +0000
committerGitHub <noreply@github.com>2022-10-28 17:12:05 +0000
commit60322e969f3eed39f64d7f2bf21878b6b454e154 (patch)
tree702208fcca901b3556546b2e5b06462b1b4e2a3b
parent086b5d28fb79878240198a3ebaa2e97b7eba94a1 (diff)
errors: Don't unwrap in `server::terminal_bytes` (#1876)
* server/terminal_bytes: Don't unwrap and return `Result`s instead, where appropriate. * changelog: Add PR #1876 Don't unwrap in `zellij_server::terminal_bytes`.
-rw-r--r--CHANGELOG.md1
-rw-r--r--zellij-server/src/pty.rs22
-rw-r--r--zellij-server/src/terminal_bytes.rs35
3 files changed, 40 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 583ba8741..a37740d93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* debugging: Remove calls to unwrap in `zellij_server::ui::*` (https://github.com/zellij-org/zellij/pull/1870)
* debugging: Remove calls to unwrap in `zellij_server::pty_writer` (https://github.com/zellij-org/zellij/pull/1872)
* docs(example): update the format of the themes for the example directory (https://github.com/zellij-org/zellij/pull/1877)
+* debugging: Remove calls to unwrap in `zellij_server::terminal_bytes` (https://github.com/zellij-org/zellij/pull/1876)
## [0.32.0] - 2022-10-25
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 03f87fd7a..bb5beb5dd 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -455,20 +455,23 @@ impl Pty {
.ok_or_else(|| SpawnTerminalError::GenericSpawnError("os input is none"))?
.spawn_terminal(terminal_action, quit_cb, self.default_editor.clone())?;
let terminal_bytes = task::spawn({
- let err_context = || format!("failed to run async task for terminal {terminal_id}");
+ let err_context =
+ |terminal_id: u32| format!("failed to run async task for terminal {terminal_id}");
let senders = self.bus.senders.clone();
let os_input = self
.bus
.os_input
.as_ref()
- .with_context(err_context)
+ .with_context(|| err_context(terminal_id))
.fatal()
.clone();
let debug_to_file = self.debug_to_file;
async move {
TerminalBytes::new(pid_primary, senders, os_input, debug_to_file, terminal_id)
.listen()
- .await;
+ .await
+ .with_context(|| err_context(terminal_id))
+ .fatal();
}
});
@@ -657,7 +660,9 @@ impl Pty {
terminal_id,
)
.listen()
- .await;
+ .await
+ .context("failed to spawn terminals for layout")
+ .fatal();
}
});
self.task_handles.insert(terminal_id, terminal_bytes);
@@ -758,20 +763,23 @@ impl Pty {
.ok_or_else(|| SpawnTerminalError::GenericSpawnError("os input is none"))?
.re_run_command_in_terminal(id, run_command, quit_cb)?;
let terminal_bytes = task::spawn({
- let err_context = || format!("failed to run async task for pane {pane_id:?}");
+ let err_context =
+ |pane_id| format!("failed to run async task for pane {pane_id:?}");
let senders = self.bus.senders.clone();
let os_input = self
.bus
.os_input
.as_ref()
- .with_context(err_context)
+ .with_context(|| err_context(pane_id))
.fatal()
.clone();
let debug_to_file = self.debug_to_file;
async move {
TerminalBytes::new(pid_primary, senders, os_input, debug_to_file, id)
.listen()
- .await;
+ .await
+ .with_context(|| err_context(pane_id))
+ .fatal();
}
});
diff --git a/zellij-server/src/terminal_bytes.rs b/zellij-server/src/terminal_bytes.rs
index 4fa1e4568..d313ec5d1 100644
--- a/zellij-server/src/terminal_bytes.rs
+++ b/zellij-server/src/terminal_bytes.rs
@@ -10,7 +10,7 @@ use std::{
};
use zellij_utils::{
async_std,
- errors::{get_current_ctx, ContextType},
+ errors::{get_current_ctx, prelude::*, ContextType},
logging::debug_to_file,
};
@@ -63,7 +63,7 @@ impl TerminalBytes {
last_render: Instant::now(),
}
}
- pub async fn listen(&mut self) {
+ pub async fn listen(&mut self) -> Result<()> {
// This function reads bytes from the pty and then sends them as
// ScreenInstruction::PtyBytes to screen to be parsed there
// We also send a separate instruction to Screen to render as ScreenInstruction::Render
@@ -75,6 +75,8 @@ impl TerminalBytes {
// only send a render instruction sparingly, giving screen time to process bytes and render
// while still allowing the user to see an indication that things are happening (the
// sparing render instructions)
+ let err_context = || "failed to listen for bytes from PTY".to_string();
+
let mut err_ctx = get_current_ctx();
err_ctx.add_call(ContextType::AsyncTask);
let mut buf = [0u8; 65536];
@@ -82,8 +84,10 @@ impl TerminalBytes {
match self.deadline_read(&mut buf).await {
ReadResult::Ok(0) | ReadResult::Err(_) => break, // EOF or error
ReadResult::Timeout => {
- let time_to_send_render =
- self.async_send_to_screen(ScreenInstruction::Render).await;
+ let time_to_send_render = self
+ .async_send_to_screen(ScreenInstruction::Render)
+ .await
+ .with_context(err_context)?;
self.update_render_send_time(time_to_send_render);
// next read does not need a deadline as we just rendered everything
self.render_deadline = None;
@@ -98,11 +102,14 @@ impl TerminalBytes {
self.terminal_id,
bytes.to_vec(),
))
- .await;
+ .await
+ .with_context(err_context)?;
if !self.backed_up {
// we're not backed up, let's send an immediate render instruction
- let time_to_send_render =
- self.async_send_to_screen(ScreenInstruction::Render).await;
+ let time_to_send_render = self
+ .async_send_to_screen(ScreenInstruction::Render)
+ .await
+ .with_context(err_context)?;
self.update_render_send_time(time_to_send_render);
self.last_render = Instant::now();
}
@@ -113,16 +120,22 @@ impl TerminalBytes {
},
}
}
- self.async_send_to_screen(ScreenInstruction::Render).await;
+ self.async_send_to_screen(ScreenInstruction::Render)
+ .await
+ .with_context(err_context)?;
+ Ok(())
}
- async fn async_send_to_screen(&self, screen_instruction: ScreenInstruction) -> Duration {
+ async fn async_send_to_screen(
+ &self,
+ screen_instruction: ScreenInstruction,
+ ) -> Result<Duration> {
// returns the time it blocked the thread for
let sent_at = Instant::now();
let senders = self.senders.clone();
task::spawn_blocking(move || senders.send_to_screen(screen_instruction))
.await
- .unwrap();
- sent_at.elapsed()
+ .context("failed to async-send to screen")?;
+ Ok(sent_at.elapsed())
}
fn update_render_send_time(&mut self, time_to_send_render: Duration) {
match self.minimum_render_send_time.as_mut() {