diff options
author | har7an <99636919+har7an@users.noreply.github.com> | 2022-10-28 17:12:05 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-28 17:12:05 +0000 |
commit | 60322e969f3eed39f64d7f2bf21878b6b454e154 (patch) | |
tree | 702208fcca901b3556546b2e5b06462b1b4e2a3b | |
parent | 086b5d28fb79878240198a3ebaa2e97b7eba94a1 (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.md | 1 | ||||
-rw-r--r-- | zellij-server/src/pty.rs | 22 | ||||
-rw-r--r-- | zellij-server/src/terminal_bytes.rs | 35 |
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() { |