Skip to content

Conversation

@MichaReiser
Copy link
Member

Summary

Run the request and notification handlers in a catch_unwind that ensures that a handler failure doesn't tear down the entire server process. ty now also responds with an appropriate error instead of just never responding to the client's request. This has the advantage that e.g. VS code stops sending new diangostic pull requests for a file on which the server crashed before.

I considered wrapping local notifications handlers in catch_unwind but decided against it. Local notifications are used to update the server state. An out of date server state can lead to all sort of errors because the ranges are of. That's why I think it's better to still crash the server.

Test Plan

  • Tested that ty shows an error pop up and the backtrace when a background task panics. The server keeps running
  • Tested that ty shows an error error pop up and the backtrace when a local task panics. the server crashes.

@MichaReiser MichaReiser added server Related to the LSP server ty Multi-file analysis & type inference labels May 22, 2025
@github-actions
Copy link
Contributor

github-actions bot commented May 22, 2025

mypy_primer results

No ecosystem changes detected ✅

@MichaReiser MichaReiser force-pushed the micha/panic-handlers-backround-threads branch from 09d5dbc to 3f64170 Compare May 22, 2025 13:07
@MichaReiser MichaReiser changed the title [ty] Abort process if worker thread panics [ty] Gracefully handle salsa cancellations and panics in background handlers May 22, 2025

/// Checks all open files in the project and its dependencies.
pub fn check(&self) -> Result<Vec<Diagnostic>, Cancelled> {
pub fn check(&self) -> Vec<Diagnostic> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to remove all Results from here for now because the server already uses many salsa APIs that aren't wrapped in a salsa::Cancelled::catch. Instead, I decided that the server request handlers catch salsa cancellations (only necessary for background tasks because:

  • Only local tasks can mutate the DB
  • All local tasks run on the main loop thread.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not hugely familiar with this part of the code, but this rationale sounds reasonable

let (id, params) = cast_request::<R>(req)?;
Ok(Task::local(|session, notifier, requester, responder| {
let _span = tracing::trace_span!("request", %id, method = R::METHOD).entered();
let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The span is very useful and tracing is just way too verbose.

Ok(response) => Some(response),
Err(error) => {
if error.payload.downcast_ref::<salsa::Cancelled>().is_some() {
// Request was cancelled by Salsa. TOOD: Retry
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I leave this for another PR, there's already enough going on in this PR

@MichaReiser MichaReiser marked this pull request as ready for review May 22, 2025 13:08
@MichaReiser MichaReiser requested review from dhruvmanila and removed request for AlexWaygood, carljm, dcreager and sharkdp May 22, 2025 13:08
@github-actions
Copy link
Contributor

github-actions bot commented May 22, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@MichaReiser MichaReiser changed the title [ty] Gracefully handle salsa cancellations and panics in background handlers [ty] Gracefully handle salsa cancellations and panics in background requests May 23, 2025

/// Checks all open files in the project and its dependencies.
pub fn check(&self) -> Result<Vec<Diagnostic>, Cancelled> {
pub fn check(&self) -> Vec<Diagnostic> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not hugely familiar with this part of the code, but this rationale sounds reasonable

Copy link
Member

@dhruvmanila dhruvmanila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Comment on lines +182 to +185
let message = format!("request handler {error}");

Some(Err(Error {
code: lsp_server::ErrorCode::InternalError,
error: anyhow!(message),
}))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could probably use LSPResult::with_failure_code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't know about this method. I'll leave it as is because I use the lsp_server Error type in #18273

Comment on lines -118 to +125
// The new PanicInfoHook name requires MSRV >= 1.82
#[expect(deprecated)]
type PanicHook = Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>;
type PanicHook = Box<dyn Fn(&PanicHookInfo<'_>) + 'static + Sync + Send>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this change for ruff_server as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to backport this entire stack to ruff

@MichaReiser MichaReiser force-pushed the micha/server-panic branch from 8fcdf96 to ccd14a5 Compare May 26, 2025 11:59
@MichaReiser MichaReiser force-pushed the micha/panic-handlers-backround-threads branch from 3f64170 to 836fc57 Compare May 26, 2025 12:07
Base automatically changed from micha/server-panic to main May 26, 2025 12:09
@MichaReiser MichaReiser force-pushed the micha/panic-handlers-backround-threads branch from 836fc57 to 3fe52c6 Compare May 26, 2025 12:10
@MichaReiser MichaReiser changed the title [ty] Gracefully handle salsa cancellations and panics in background requests [ty] Gracefully handle salsa cancellations and panics in background request handlers May 26, 2025
@MichaReiser MichaReiser merged commit d8216fa into main May 26, 2025
35 checks passed
@MichaReiser MichaReiser deleted the micha/panic-handlers-backround-threads branch May 26, 2025 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants