diff options
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 16 |
1 files changed, 10 insertions, 6 deletions
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; | |||
4 | mod subscriptions; | 4 | mod subscriptions; |
5 | pub(crate) mod pending_requests; | 5 | pub(crate) mod pending_requests; |
6 | 6 | ||
7 | use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Instant}; | 7 | use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant}; |
8 | 8 | ||
9 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; | 9 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; |
10 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; | 10 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
@@ -565,7 +565,7 @@ impl<'a> PoolDispatcher<'a> { | |||
565 | ) -> Result<&mut Self> | 565 | ) -> Result<&mut Self> |
566 | where | 566 | where |
567 | R: req::Request + 'static, | 567 | R: req::Request + 'static, |
568 | R::Params: DeserializeOwned + Send + 'static, | 568 | R::Params: DeserializeOwned + panic::UnwindSafe + 'static, |
569 | R::Result: Serialize + 'static, | 569 | R::Result: Serialize + 'static, |
570 | { | 570 | { |
571 | let (id, params) = match self.parse::<R>() { | 571 | let (id, params) = match self.parse::<R>() { |
@@ -574,8 +574,12 @@ impl<'a> PoolDispatcher<'a> { | |||
574 | return Ok(self); | 574 | return Ok(self); |
575 | } | 575 | } |
576 | }; | 576 | }; |
577 | let result = f(self.world, params); | 577 | let world = panic::AssertUnwindSafe(&mut *self.world); |
578 | let task = result_to_task::<R>(id, result); | 578 | let task = panic::catch_unwind(move || { |
579 | let result = f(world.0, params); | ||
580 | result_to_task::<R>(id, result) | ||
581 | }) | ||
582 | .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; | ||
579 | on_task(task, self.msg_sender, self.pending_requests, self.world); | 583 | on_task(task, self.msg_sender, self.pending_requests, self.world); |
580 | Ok(self) | 584 | Ok(self) |
581 | } | 585 | } |
@@ -610,7 +614,7 @@ impl<'a> PoolDispatcher<'a> { | |||
610 | fn parse<R>(&mut self) -> Option<(RequestId, R::Params)> | 614 | fn parse<R>(&mut self) -> Option<(RequestId, R::Params)> |
611 | where | 615 | where |
612 | R: req::Request + 'static, | 616 | R: req::Request + 'static, |
613 | R::Params: DeserializeOwned + Send + 'static, | 617 | R::Params: DeserializeOwned + 'static, |
614 | { | 618 | { |
615 | let req = self.req.take()?; | 619 | let req = self.req.take()?; |
616 | let (id, params) = match req.extract::<R::Params>(R::METHOD) { | 620 | let (id, params) = match req.extract::<R::Params>(R::METHOD) { |
@@ -647,7 +651,7 @@ impl<'a> PoolDispatcher<'a> { | |||
647 | fn result_to_task<R>(id: RequestId, result: Result<R::Result>) -> Task | 651 | fn result_to_task<R>(id: RequestId, result: Result<R::Result>) -> Task |
648 | where | 652 | where |
649 | R: req::Request + 'static, | 653 | R: req::Request + 'static, |
650 | R::Params: DeserializeOwned + Send + 'static, | 654 | R::Params: DeserializeOwned + 'static, |
651 | R::Result: Serialize + 'static, | 655 | R::Result: Serialize + 'static, |
652 | { | 656 | { |
653 | let response = match result { | 657 | let response = match result { |