diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 6373240d5f9..47222cd0ac2 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -621,17 +621,32 @@ pub fn handle_formatting(
 
     let output = rustfmt.wait_with_output()?;
     let captured_stdout = String::from_utf8(output.stdout)?;
+
     if !output.status.success() {
-        return Err(LspError::new(
-            -32900,
-            format!(
-                r#"rustfmt exited with:
-            Status: {}
-            stdout: {}"#,
-                output.status, captured_stdout,
-            ),
-        )
-        .into());
+        match output.status.code() {
+            Some(1) => {
+                // While `rustfmt` doesn't have a specific exit code for parse errors this is the
+                // likely cause exiting with 1. Most Language Servers swallow parse errors on
+                // formatting because otherwise an error is surfaced to the user on top of the
+                // syntax error diagnostics they're already receiving. This is especially jarring
+                // if they have format on save enabled.
+                log::info!("rustfmt exited with status 1, assuming parse error and ignoring");
+                return Ok(None);
+            }
+            _ => {
+                // Something else happened - e.g. `rustfmt` is missing or caught a signal
+                return Err(LspError::new(
+                    -32900,
+                    format!(
+                        r#"rustfmt exited with:
+                           Status: {}
+                           stdout: {}"#,
+                        output.status, captured_stdout,
+                    ),
+                )
+                .into());
+            }
+        }
     }
 
     Ok(Some(vec![TextEdit {