about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-09 09:44:40 +0000
committerbors <bors@rust-lang.org>2024-05-09 09:44:40 +0000
commit85b17d4e11a2690c6546705f9136a99d293ad0b5 (patch)
tree67a42f86722aac0331c1a87521d3f85c5b19f794
parent24ef42aafc03cf1bf4298a0fec1ca313979169d7 (diff)
parent8ca11468fb804303742125c5252df6c10d5c90cd (diff)
downloadrust-85b17d4e11a2690c6546705f9136a99d293ad0b5.tar.gz
rust-85b17d4e11a2690c6546705f9136a99d293ad0b5.zip
Auto merge of #17207 - Wilfred:serde_invalid_data, r=lnicola
fix: Report all LSP protocol errors with invalid_data

Previously we did not use invalid_data for serde errors, making it harder to understand errors when the client sends malformed data to the server.
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/src/msg.rs28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs b/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs
index 71e5933689a..53c64796f28 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs
+++ b/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs
@@ -153,6 +153,14 @@ pub struct Notification {
     pub params: serde_json::Value,
 }
 
+fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
+    io::Error::new(io::ErrorKind::InvalidData, error)
+}
+
+macro_rules! invalid_data {
+    ($($tt:tt)*) => (invalid_data(format!($($tt)*)))
+}
+
 impl Message {
     pub fn read(r: &mut impl BufRead) -> io::Result<Option<Message>> {
         Message::_read(r)
@@ -162,7 +170,14 @@ impl Message {
             None => return Ok(None),
             Some(text) => text,
         };
-        let msg = serde_json::from_str(&text)?;
+
+        let msg = match serde_json::from_str(&text) {
+            Ok(msg) => msg,
+            Err(e) => {
+                return Err(invalid_data!("malformed LSP payload: {:?}", e));
+            }
+        };
+
         Ok(Some(msg))
     }
     pub fn write(self, w: &mut impl Write) -> io::Result<()> {
@@ -240,13 +255,6 @@ impl Notification {
 }
 
 fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
-    fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
-        io::Error::new(io::ErrorKind::InvalidData, error)
-    }
-    macro_rules! invalid_data {
-        ($($tt:tt)*) => (invalid_data(format!($($tt)*)))
-    }
-
     let mut size = None;
     let mut buf = String::new();
     loop {
@@ -264,12 +272,12 @@ fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
         let mut parts = buf.splitn(2, ": ");
         let header_name = parts.next().unwrap();
         let header_value =
-            parts.next().ok_or_else(|| invalid_data(format!("malformed header: {:?}", buf)))?;
+            parts.next().ok_or_else(|| invalid_data!("malformed header: {:?}", buf))?;
         if header_name.eq_ignore_ascii_case("Content-Length") {
             size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
         }
     }
-    let size: usize = size.ok_or_else(|| invalid_data("no Content-Length".to_owned()))?;
+    let size: usize = size.ok_or_else(|| invalid_data!("no Content-Length"))?;
     let mut buf = buf.into_bytes();
     buf.resize(size, 0);
     inp.read_exact(&mut buf)?;