From 418fbc8662d4a70e5081cc422b4bc8ded4b923d8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 24 Oct 2019 09:52:32 +0300 Subject: don't die if a sync task panics --- crates/ra_lsp_server/src/main_loop.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 0b5d9c44d..1a87706fe 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -4,7 +4,7 @@ mod handlers; mod subscriptions; pub(crate) mod pending_requests; -use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Instant}; +use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant}; use crossbeam_channel::{select, unbounded, RecvError, Sender}; use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; @@ -565,7 +565,7 @@ impl<'a> PoolDispatcher<'a> { ) -> Result<&mut Self> where R: req::Request + 'static, - R::Params: DeserializeOwned + Send + 'static, + R::Params: DeserializeOwned + panic::UnwindSafe + 'static, R::Result: Serialize + 'static, { let (id, params) = match self.parse::() { @@ -574,8 +574,12 @@ impl<'a> PoolDispatcher<'a> { return Ok(self); } }; - let result = f(self.world, params); - let task = result_to_task::(id, result); + let world = panic::AssertUnwindSafe(&mut *self.world); + let task = panic::catch_unwind(move || { + let result = f(world.0, params); + result_to_task::(id, result) + }) + .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; on_task(task, self.msg_sender, self.pending_requests, self.world); Ok(self) } @@ -610,7 +614,7 @@ impl<'a> PoolDispatcher<'a> { fn parse(&mut self) -> Option<(RequestId, R::Params)> where R: req::Request + 'static, - R::Params: DeserializeOwned + Send + 'static, + R::Params: DeserializeOwned + 'static, { let req = self.req.take()?; let (id, params) = match req.extract::(R::METHOD) { @@ -647,7 +651,7 @@ impl<'a> PoolDispatcher<'a> { fn result_to_task(id: RequestId, result: Result) -> Task where R: req::Request + 'static, - R::Params: DeserializeOwned + Send + 'static, + R::Params: DeserializeOwned + 'static, R::Result: Serialize + 'static, { let response = match result { -- cgit v1.2.3