Skip to content

fix: metamodel query error handling#148

Merged
asharkhan3101 merged 1 commit into
coder3101:mainfrom
AlexCannonball:fix/metamodel-query-err-handling
Jul 22, 2026
Merged

fix: metamodel query error handling#148
asharkhan3101 merged 1 commit into
coder3101:mainfrom
AlexCannonball:fix/metamodel-query-err-handling

Conversation

@AlexCannonball

Copy link
Copy Markdown
Contributor

Fix the metamodel query irrecoverable error handling as we discussed in #145 (comment)

Expected behavior

When executing the rewritten initialization block:

let metamodel_query = Query::new(&language, &generate_metamodel_query())
    .inspect_err(trace_error)
    .expect("Tree-sitter query compilation failed");

In the highly unlikely event that Query::new returns an Err (e.g., due to a broken embedded SCM query structure), the system undergoes a graceful, multi-stage teardown instead of an abrupt termination:

  1. Synchronous Logging Dispatch (.inspect_err):
    The inspect_err combinator immediately intercepts the QueryError and triggers the trace_error closure. This formats and dispatches the details straight into the logging pipeline via tracing::error!.

    • LSP Channel Interaction: The ClientLogger captures this event and performs a try_send into the tokio::sync::mpsc buffer queue.
  2. Panicking with Context (.expect):
    Since the result evaluates to Err, .expect() forces the current thread to panic, carrying the message "Tree-sitter query compilation failed".

  3. Runtime Interception (CatchUnwindLayer):
    Because the async_lsp server topology utilizes CatchUnwindLayer::default(), the panic does not instantly kill the OS process.

    • The layer catches the winding stack, safely translates the runtime failure into an appropriate JSON-RPC response or cleanly terminates the active transport streams, and allows the asynchronous loop to gracefully unwind out of main().
  4. Guaranteed Buffer Flushing via RAII (WorkerGuard):
    As main() completes its termination lifecycle, Rust drops all remaining active resources in local scopes.

    • Crucially, the _log_guard variable (returned from log::install) is dropped. Its underlying tracing_appender::non_blocking::WorkerGuard destructor explicitly forces a blocking, synchronous flush of all remaining logs sitting in the background thread directly into protols.log.
    • This completely bypasses the need for arbitrary std::thread::sleep(50) pauses, guaranteeing zero diagnostic data loss.

I've tested this error on VS Code client:

image

and neovim:

image

So it depends on the client, whether the stderr text will be displayed.

However, the log file protols.log includes this:

2026-07-22T17:31:40.301120Z ERROR protols::state: Critical SCM error: Failed to compile embedded Tree-sitter query for metadata extraction. Details: QueryError { row: 0, column: 0, offset: 0, message: "invalid\n^", kind: Syntax }

I expect that only protols developers could theoretically encounter this issue during internal development. It will never be released to regular users, as our test suite would fail the build beforehand. So it seem to be a good UX/DX.

@asharkhan3101
asharkhan3101 merged commit 17dc3d3 into coder3101:main Jul 22, 2026
6 checks passed
@AlexCannonball
AlexCannonball deleted the fix/metamodel-query-err-handling branch July 22, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants