Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
moving catch_unwind to panic module
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Leite committed Nov 17, 2022
1 parent 6da7eb5 commit c541796
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 56 deletions.
52 changes: 1 addition & 51 deletions crates/rome_diagnostics/src/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ pub mod display;
pub mod error;
pub mod location;
pub mod serde;

use std::panic::UnwindSafe;
pub mod panic;

#[doc(hidden)]
// Convenience re-export for procedural macro
Expand All @@ -28,55 +27,6 @@ pub use display::{
pub use error::{Error, Result};
pub use location::{FileId, FilePath, LineIndex, LineIndexBuf, Location, Resource, SourceCode};

#[derive(Default, Debug)]
pub struct PanicError {
pub info: String,
pub backtrace: Option<std::backtrace::Backtrace>,
}

thread_local! {
static LAST_PANIC: std::cell::Cell<Option<PanicError>> = std::cell::Cell::new(None);
}

impl std::fmt::Display for PanicError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let r = f.write_fmt(format_args!("{}\n", self.info));
if let Some(backtrace) = &self.backtrace {
f.write_fmt(format_args!("Backtrace: {}", backtrace))
} else {
r
}
}
}

/// Take and set a specific panic hook before calling `f` inside a `catch_unwind`, then
/// return the old set_hook.
///
/// If `f` panicks am `Error` with the panic message plus backtrace will be returned.
pub fn catch_unwind<F, R>(f: F) -> Result<R, PanicError>
where
F: FnOnce() -> R + UnwindSafe,
{
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(|info| {
let info = info.to_string();
let backtrace = std::backtrace::Backtrace::capture();
LAST_PANIC.with(|cell| {
cell.set(Some(PanicError {
info,
backtrace: Some(backtrace),
}))
})
}));

let result = std::panic::catch_unwind(f)
.map_err(|_| LAST_PANIC.with(|cell| cell.take()).unwrap_or_default());

std::panic::set_hook(prev);

result
}

pub mod prelude {
//! Anonymously re-exports all the traits declared by this module, this is
//! intended to be imported as `use rome_diagnostics::v2::prelude::*;` to
Expand Down
51 changes: 51 additions & 0 deletions crates/rome_diagnostics/src/v2/panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

use std::panic::UnwindSafe;

#[derive(Default, Debug)]
pub struct PanicError {
pub info: String,
pub backtrace: Option<std::backtrace::Backtrace>,
}

thread_local! {
static LAST_PANIC: std::cell::Cell<Option<PanicError>> = std::cell::Cell::new(None);
}

impl std::fmt::Display for PanicError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let r = f.write_fmt(format_args!("{}\n", self.info));
if let Some(backtrace) = &self.backtrace {
f.write_fmt(format_args!("Backtrace: {}", backtrace))
} else {
r
}
}
}

/// Take and set a specific panic hook before calling `f` inside a `catch_unwind`, then
/// return the old set_hook.
///
/// If `f` panicks am `Error` with the panic message plus backtrace will be returned.
pub fn catch_unwind<F, R>(f: F) -> Result<R, PanicError>
where
F: FnOnce() -> R + UnwindSafe,
{
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(|info| {
let info = info.to_string();
let backtrace = std::backtrace::Backtrace::capture();
LAST_PANIC.with(|cell| {
cell.set(Some(PanicError {
info,
backtrace: Some(backtrace),
}))
})
}));

let result = std::panic::catch_unwind(f)
.map_err(|_| LAST_PANIC.with(|cell| cell.take()).unwrap_or_default());

std::panic::set_hook(prev);

result
}
10 changes: 5 additions & 5 deletions crates/rome_lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ impl LanguageServer for LSPServer {
}

async fn code_action(&self, params: CodeActionParams) -> LspResult<Option<CodeActionResponse>> {
rome_diagnostics::v2::catch_unwind(move || {
rome_diagnostics::v2::panic::catch_unwind(move || {
handlers::analysis::code_actions(&self.session, params).map_err(into_lsp_error)
})
.map_err(into_lsp_error)?
Expand All @@ -315,7 +315,7 @@ impl LanguageServer for LSPServer {
&self,
params: DocumentFormattingParams,
) -> LspResult<Option<Vec<TextEdit>>> {
rome_diagnostics::v2::catch_unwind(move || {
rome_diagnostics::v2::panic::catch_unwind(move || {
handlers::formatting::format(&self.session, params).map_err(into_lsp_error)
})
.map_err(into_lsp_error)?
Expand All @@ -325,7 +325,7 @@ impl LanguageServer for LSPServer {
&self,
params: DocumentRangeFormattingParams,
) -> LspResult<Option<Vec<TextEdit>>> {
rome_diagnostics::v2::catch_unwind(move || {
rome_diagnostics::v2::panic::catch_unwind(move || {
handlers::formatting::format_range(&self.session, params).map_err(into_lsp_error)
})
.map_err(into_lsp_error)?
Expand All @@ -335,14 +335,14 @@ impl LanguageServer for LSPServer {
&self,
params: DocumentOnTypeFormattingParams,
) -> LspResult<Option<Vec<TextEdit>>> {
rome_diagnostics::v2::catch_unwind(move || {
rome_diagnostics::v2::panic::catch_unwind(move || {
handlers::formatting::format_on_type(&self.session, params).map_err(into_lsp_error)
})
.map_err(into_lsp_error)?
}

async fn rename(&self, params: RenameParams) -> LspResult<Option<WorkspaceEdit>> {
rome_diagnostics::v2::catch_unwind(move || {
rome_diagnostics::v2::panic::catch_unwind(move || {
let rename_enabled = self
.session
.config
Expand Down

0 comments on commit c541796

Please sign in to comment.