diff --git a/crates/ra_proc_macro_srv/src/cli.rs b/crates/ra_proc_macro_srv/src/cli.rs
index c7f41e4485f..ded1bcdbcb1 100644
--- a/crates/ra_proc_macro_srv/src/cli.rs
+++ b/crates/ra_proc_macro_srv/src/cli.rs
@@ -4,16 +4,13 @@ use crate::{expand_task, list_macros};
 use ra_proc_macro::msg::{self, Message};
 use std::io;
 
-pub fn run() {
+pub fn run() -> io::Result<()> {
     loop {
-        let req = match read_request() {
-            Err(err) => {
-                // Panic here, as the stdin pipe may be closed.
-                // Otherwise, client will be restarted the service anyway.
-                panic!("Read message error on ra_proc_macro_srv: {}", err);
-            }
-            Ok(None) => continue,
-            Ok(Some(req)) => req,
+        // bubble up the error for read request,
+        // as the stdin pipe may be closed.
+        let req = match read_request()? {
+            None => continue,
+            Some(req) => req,
         };
 
         let res = match req {
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index e8d5dad6577..22a84b50c09 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -66,7 +66,7 @@ fn setup_logging() -> Result<()> {
 }
 
 fn run_proc_macro_srv() -> Result<()> {
-    ra_proc_macro_srv::cli::run();
+    ra_proc_macro_srv::cli::run()?;
     Ok(())
 }