diff --git a/codec/src/lib.rs b/codec/src/lib.rs index c6337598d..164b033e1 100644 --- a/codec/src/lib.rs +++ b/codec/src/lib.rs @@ -37,8 +37,8 @@ use wezterm_term::color::ColorPalette; use wezterm_term::{Alert, ClipboardSelection, StableRowIndex, TerminalSize}; #[derive(Error, Debug)] -#[error("Corrupt Response")] -pub struct CorruptResponse; +#[error("Corrupt Response: {0}")] +pub struct CorruptResponse(String); /// Returns the encoded length of the leb128 representation of value fn encoded_length(value: u64) -> usize { @@ -173,30 +173,39 @@ async fn decode_raw_async( r: &mut R, max_serial: Option, ) -> anyhow::Result { - let len = read_u64_async(r).await.context("reading PDU length")?; + let len = read_u64_async(r) + .await + .context("decode_raw_async failed to read PDU length")?; let (len, is_compressed) = if (len & COMPRESSED_MASK) != 0 { (len & !COMPRESSED_MASK, true) } else { (len, false) }; - let serial = read_u64_async(r).await.context("reading PDU serial")?; + let serial = read_u64_async(r) + .await + .context("decode_raw_async failed to read PDU serial")?; if let Some(max_serial) = max_serial { if serial > max_serial && max_serial > 0 { - return Err(CorruptResponse).context("decode_raw"); + return Err(CorruptResponse(format!( + "decode_raw_async: serial {serial} is implausibly large \ + (bigger than {max_serial})" + )) + .into()); } } - let ident = read_u64_async(r).await.context("reading PDU ident")?; + let ident = read_u64_async(r) + .await + .context("decode_raw_async failed to read PDU ident")?; let data_len = match (len as usize).overflowing_sub(encoded_length(ident) + encoded_length(serial)) { (_, true) => { - anyhow::bail!( - "sizes don't make sense: len:{} serial:{} (enc={}) ident:{} (enc={})", - len, - serial, + return Err(CorruptResponse(format!( + "decode_raw_async: sizes don't make sense: \ + len:{len} serial:{serial} (enc={}) ident:{ident} (enc={})", encoded_length(serial), - ident, encoded_length(ident) - ); + )) + .into()); } (data_len, false) => data_len, }; @@ -210,7 +219,8 @@ async fn decode_raw_async( let mut data = vec![0u8; data_len]; r.read_exact(&mut data).await.with_context(|| { format!( - "reading {} bytes of data for PDU of length {} with serial={} ident={}", + "decode_raw_async failed to read {} bytes of data \ + for PDU of length {} with serial={} ident={}", data_len, len, serial, ident ) })?; diff --git a/wezterm-client/src/client.rs b/wezterm-client/src/client.rs index 7e6d7c78e..7d43934d3 100644 --- a/wezterm-client/src/client.rs +++ b/wezterm-client/src/client.rs @@ -1167,21 +1167,24 @@ impl Client { } else if err.root_cause().is::() { "Received an implausible and likely corrupt response from \ the server. This can happen if the remote host outputs \ - to stdout prior to running commands." + to stdout prior to running commands. \ + Check your shell startup!" .to_string() } else if err.root_cause().is::() { "Internal channel was closed prior to sending request. \ This may indicate that the remote host output invalid data \ - to stdout prior to running the requested command" + to stdout prior to running the requested command. \ + Check your shell startup!" .to_string() } else { format!( "Please install the same version of wezterm on both \ the client and server! \ - The server reported error '{}' while being asked for its \ + The server reported error '{err}' while being asked for its \ version. This likely means that the server is older \ - than the client.\n", - err + than the client, but it could also happen if the remote \ + host outputs to stdout prior to running commands. \ + Check your shell startup!", ) }; ui.output_str(&msg);