Skip to content

Commit

Permalink
LS: Inline ls_catch_unwind (#6506)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkaput authored Oct 23, 2024
1 parent 516ca3a commit ce412d8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 28 deletions.
6 changes: 3 additions & 3 deletions crates/cairo-lang-language-server/src/lang/db/swapper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashSet;
use std::panic::{AssertUnwindSafe, catch_unwind};
use std::sync::Arc;
use std::time::{Duration, SystemTime};

Expand All @@ -11,7 +12,6 @@ use tracing::{error, warn};

use crate::lang::db::AnalysisDatabase;
use crate::lang::lsp::LsProtoGroup;
use crate::server::panic::ls_catch_unwind;
use crate::{Tricks, env_config};

/// Swaps entire [`AnalysisDatabase`] with empty one periodically.
Expand Down Expand Up @@ -65,11 +65,11 @@ impl AnalysisDatabaseSwapper {
return;
}

let Ok(new_db) = ls_catch_unwind(|| {
let Ok(new_db) = catch_unwind(AssertUnwindSafe(|| {
let mut new_db = AnalysisDatabase::new(tricks);
ensure_exists_in_db(&mut new_db, db, open_files.iter());
new_db
}) else {
})) else {
error!("caught panic when preparing new db for swap");
return;
};
Expand Down
22 changes: 1 addition & 21 deletions crates/cairo-lang-language-server/src/server/panic.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
use std::any::Any;
use std::panic::{AssertUnwindSafe, catch_unwind};

use anyhow::anyhow;
use lsp_server::ErrorCode;
use salsa::Cancelled;
use tracing::{debug, error};

use crate::lsp::result::{LSPError, LSPResult};

/// Invokes a closure, capturing the cause of an unwinding panic if one occurs and builds
/// [`LSPResult`] out of it.
pub fn ls_catch_unwind<T>(f: impl FnOnce() -> T) -> LSPResult<T> {
catch_unwind(AssertUnwindSafe(f)).map_err(|err| {
if is_cancelled(&err) {
debug!("LSP worker thread was cancelled");
LSPError::new(anyhow!("LSP worker thread was cancelled"), ErrorCode::ServerCancelled)
} else {
error!("caught panic in LSP worker thread");
LSPError::new(anyhow!("caught panic in LSP worker thread"), ErrorCode::InternalError)
}
})
}

/// Checks if the panic was caused by Salsa cancellation.
fn is_cancelled(err: &(dyn Any + Send)) -> bool {
pub fn is_cancelled(err: &(dyn Any + Send)) -> bool {
// Salsa is broken and sometimes when cancelled throws regular assert instead of `Cancelled`.
err.is::<Cancelled>()
|| err.downcast_ref::<&str>().is_some_and(|msg| {
Expand Down
28 changes: 24 additions & 4 deletions crates/cairo-lang-language-server/src/server/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// | Commit: 46a457318d8d259376a2b458b3f814b9b795fe69 |
// +------------------------------------------------------------+

use std::panic::{AssertUnwindSafe, catch_unwind};

use anyhow::anyhow;
use lsp_server::{ErrorCode, ExtractError, Notification, Request, RequestId};
use lsp_types::notification::{
Cancel, DidChangeConfiguration, DidChangeTextDocument, DidChangeWatchedFiles,
Expand All @@ -15,12 +18,12 @@ use lsp_types::request::{
CodeActionRequest, Completion, ExecuteCommand, Formatting, GotoDefinition, HoverRequest,
Request as RequestTrait, SemanticTokensFullRequest,
};
use tracing::{error, warn};
use tracing::{debug, error, warn};

use super::client::Responder;
use crate::lsp::ext::{ExpandMacro, ProvideVirtualFile, ViewAnalyzedCrates};
use crate::lsp::result::{LSPError, LSPResult, LSPResultEx};
use crate::server::panic::ls_catch_unwind;
use crate::server::panic::is_cancelled;
use crate::server::schedule::{BackgroundSchedule, Task};
use crate::state::State;

Expand Down Expand Up @@ -122,8 +125,25 @@ fn background_request_task<'a, R: traits::BackgroundDocumentRequestHandler>(
Ok(Task::background(schedule, move |state: &State| {
let state_snapshot = state.snapshot();
Box::new(move |notifier, responder| {
let result = ls_catch_unwind(|| R::run_with_snapshot(state_snapshot, notifier, params))
.and_then(|res| res);
let result = catch_unwind(AssertUnwindSafe(|| {
R::run_with_snapshot(state_snapshot, notifier, params)
}))
.map_err(|err| {
if is_cancelled(&err) {
debug!("LSP worker thread was cancelled");
LSPError::new(
anyhow!("LSP worker thread was cancelled"),
ErrorCode::ServerCancelled,
)
} else {
error!("caught panic in LSP worker thread");
LSPError::new(
anyhow!("caught panic in LSP worker thread"),
ErrorCode::InternalError,
)
}
})
.and_then(|res| res);
respond::<R>(id, result, &responder);
})
}))
Expand Down

0 comments on commit ce412d8

Please sign in to comment.