Skip to content

Commit

Permalink
Add LSP panic handling (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
gimalay authored Jan 20, 2025
1 parent b6dfd0d commit 695bc3b
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 23 deletions.
5 changes: 4 additions & 1 deletion crates/iwes/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
)
.init();
} else {
tracing_subscriber::fmt::init()
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.with_writer(std::io::stderr)
.init();
}

info!("starting IWE LSP server");
Expand Down
24 changes: 17 additions & 7 deletions crates/iwes/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::Instant;
use std::panic;

use anyhow::{bail, Result};
use crossbeam_channel::{select, Receiver, Sender};
Expand All @@ -7,13 +7,12 @@ use log::{debug, error};
use lsp_server::{ErrorCode, Message, Request};
use lsp_server::{Notification, Response};
use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyOutgoingCallsParams,
CodeActionParams, DidChangeTextDocumentParams, DidSaveTextDocumentParams,
DocumentFormattingParams, DocumentSymbolParams, InlayHintParams, InlineValueParams,
ReferenceParams, RenameParams, TextDocumentPositionParams, WorkspaceSymbolParams,
};
use lsp_types::{CompletionParams, GotoDefinitionParams};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde::Deserialize;
use serde_json::to_value;

use liwe::model::State;
Expand Down Expand Up @@ -68,8 +67,21 @@ impl Router {
}

pub fn run(mut self, receiver: Receiver<Message>) -> Result<()> {
use std::panic::AssertUnwindSafe;

while let Some(message) = self.next_event(&receiver) {
let shutdown = self.handle_message(message);
let shutdown = panic::catch_unwind(AssertUnwindSafe(|| self.handle_message(message)))
.unwrap_or_else(|err| {
let error_message = if let Some(string) = err.downcast_ref::<&str>() {
format!("Panic occurred with message: {}", string)
} else if let Some(string) = err.downcast_ref::<String>() {
format!("Panic occurred with message: {}", string)
} else {
"Panic occurred with unknown cause".to_string()
};
error!("Panic message: {}", error_message);
false
});

if shutdown {
return Ok(());
Expand All @@ -82,9 +94,7 @@ impl Router {
match message {
Message::Request(req) => self.on_request(req),
Message::Notification(notification) => self.on_notification(notification),
Message::Response(_) => {
return false;
}
Message::Response(_) => false,
}
}

Expand Down
17 changes: 5 additions & 12 deletions crates/iwes/src/router/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ pub struct BasePath {
}

impl BasePath {
fn new(base_path: String) -> Self {
Self { base_path }
}

fn key_to_url(&self, key: &Key) -> Url {
Url::parse(&format!("{}{}.md", self.base_path, key)).unwrap()
}
Expand Down Expand Up @@ -73,7 +69,7 @@ impl Server {
&self.database
}

pub fn handle_did_save_text_document(&mut self, params: DidSaveTextDocumentParams) {}
pub fn handle_did_save_text_document(&mut self, _: DidSaveTextDocumentParams) {}

pub fn handle_did_change_text_document(&mut self, params: DidChangeTextDocumentParams) {
self.database.update_document(
Expand All @@ -82,7 +78,7 @@ impl Server {
);
}

pub fn handle_completion(&self, params: CompletionParams) -> CompletionResponse {
pub fn handle_completion(&self, _: CompletionParams) -> CompletionResponse {
CompletionResponse::List(CompletionList {
is_incomplete: true,
items: self
Expand All @@ -95,10 +91,7 @@ impl Server {
})
}

pub fn handle_workspace_symbols(
&self,
params: WorkspaceSymbolParams,
) -> WorkspaceSymbolResponse {
pub fn handle_workspace_symbols(&self, _: WorkspaceSymbolParams) -> WorkspaceSymbolResponse {
self.database
.graph()
.paths()
Expand Down Expand Up @@ -178,12 +171,12 @@ impl Server {
.chain(
vec![hint(&format!("‹{}›", inline_refs))]
.into_iter()
.filter(|h| inline_refs > 0),
.filter(|_| inline_refs > 0),
)
.collect_vec()
}

pub fn handle_inline_values(&self, params: InlineValueParams) -> Vec<InlineValue> {
pub fn handle_inline_values(&self, _: InlineValueParams) -> Vec<InlineValue> {
vec![]
}

Expand Down
2 changes: 2 additions & 0 deletions crates/iwes/src/router/server/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ pub impl NodePath {
+ &last
}

#[allow(deprecated)]
fn to_symbol(&self, context: impl GraphContext, base_path: &BasePath) -> SymbolInformation {
let target = self.target();
let line = context.node_line_number(target).unwrap_or(0);
Expand All @@ -259,6 +260,7 @@ pub impl NodePath {
}
}

#[allow(deprecated)]
fn to_nested_symbol(
&self,
context: impl GraphContext,
Expand Down
3 changes: 3 additions & 0 deletions crates/iwes/tests/did_change_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::fixture::Fixture;
mod fixture;

#[test]
#[allow(deprecated)]
fn did_change_test_once() {
let fixture = Fixture::with(indoc! {"
# test
Expand Down Expand Up @@ -50,6 +51,7 @@ fn did_change_test_once() {
}

#[test]
#[allow(deprecated)]
fn new_file() {
let fixture = Fixture::new();

Expand Down Expand Up @@ -86,6 +88,7 @@ fn new_file() {
}

#[test]
#[allow(deprecated)]
fn did_change_test_two_times() {
let fixture = Fixture::with(indoc! {"
# test
Expand Down
5 changes: 4 additions & 1 deletion crates/iwes/tests/fixture.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[allow(unused, dead_code)]
use std::{
cell::{Cell, RefCell},
time::Duration,
Expand Down Expand Up @@ -51,18 +50,22 @@ pub fn uri(number: u32) -> Url {
Url::from_file_path(format!("/basepath/{}.md", number)).unwrap()
}

#[allow(unused, dead_code)]
pub fn uri_from(key: &str) -> Url {
Url::from_file_path(format!("/basepath/{}.md", key)).unwrap()
}

#[allow(unused, dead_code)]
pub fn action_kinds(name: &'static str) -> Option<Vec<CodeActionKind>> {
Some(vec![CodeActionKind::new(name)])
}

#[allow(unused, dead_code)]
pub fn action_kind(name: &'static str) -> Option<CodeActionKind> {
Some(CodeActionKind::new(name))
}

#[allow(unused, dead_code)]
impl Fixture {
pub fn new() -> Fixture {
Self::with("\n")
Expand Down
2 changes: 0 additions & 2 deletions crates/iwes/tests/inlay_hints_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::u32;

use indoc::indoc;
use lsp_types::{
InlayHint, InlayHintLabel, InlayHintParams, Position, Range, TextDocumentIdentifier,
Expand Down
6 changes: 6 additions & 0 deletions crates/iwes/tests/workspace_symbols_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::fixture::Fixture;
mod fixture;

#[test]
#[allow(deprecated)]
fn one_file() {
let fixture = Fixture::with(indoc! {"
# test
Expand All @@ -36,6 +37,7 @@ fn one_file() {
}

#[test]
#[allow(deprecated)]
fn one_file_two_headers() {
let fixture = Fixture::with(indoc! {"
# test
Expand Down Expand Up @@ -77,6 +79,7 @@ fn one_file_two_headers() {
}

#[test]
#[allow(deprecated)]
fn one_file_two_headers_same_level() {
let fixture = Fixture::with(indoc! {"
# test
Expand Down Expand Up @@ -118,6 +121,7 @@ fn one_file_two_headers_same_level() {
}

#[test]
#[allow(deprecated)]
fn two_files() {
let fixture = Fixture::with(indoc! {"
# test 1
Expand Down Expand Up @@ -159,6 +163,7 @@ fn two_files() {
}

#[test]
#[allow(deprecated)]
fn nested_files() {
let fixture = Fixture::with(indoc! {"
# test 1
Expand Down Expand Up @@ -202,6 +207,7 @@ fn nested_files() {
}

#[test]
#[allow(deprecated)]
fn two_nested_nested_files() {
let fixture = Fixture::with(indoc! {"
# test 1
Expand Down

0 comments on commit 695bc3b

Please sign in to comment.