Skip to content

feat: linkify Java stack traces in text documents (#1654)#1657

Merged
wenytang-ms merged 14 commits into
mainfrom
feature/stacktrace-console-1654
Jul 23, 2026
Merged

feat: linkify Java stack traces in text documents (#1654)#1657
wenytang-ms merged 14 commits into
mainfrom
feature/stacktrace-console-1654

Conversation

@wenytang-ms

@wenytang-ms wenytang-ms commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Closes #1654 (draft for design review — not ready to merge).

What & why

Developers frequently receive Java stack traces from log files, CI failures, bug reports, chat messages, and production logs. Eclipse ("Java Stack Trace Console") and IntelliJ ("Analyze Stack Trace") let users click frames from an external trace and jump to source without a running debug session.

VS Code's existing Java stack-trace linkifier only handles output that has already flowed through the integrated terminal. This PR adds the missing standalone text-document workflow.

User experience

  • Paste a Java stack trace into any untitled document and click its frames.
  • Open a .log file and click Java stack frames directly.
  • Run Java: Analyze Stack Trace to open an untitled document prefilled with the complete clipboard text.
  • When source resolution succeeds, clicking a frame opens the source at the corresponding line. If it fails, the existing class-name Quick Open fallback is used.

No active debug session is required.

Implementation

  • A DocumentLinkProvider in src/stackTraceLinkProvider.ts handles untitled documents and .log files.
  • activationEvents includes workspaceContains:**/*.java, so the extension activates when a Java workspace is opened.
  • Provider registration waits until redhat.java reaches ServerMode.STANDARD; the one-shot server-mode listener is disposed after registration.
  • Frame resolution reuses the existing session-independent vscode.java.resolveSourceUri backend. No Java backend changes are required.
  • Source resolution is lazy: the provider identifies frame ranges, while the backend is called only after a link is clicked.
  • src/stackFrameParser.ts is shared by the terminal and document link providers so both surfaces recognize the same frame syntax.

Scope and safety

The document selector covers:

  • Untitled documents, including the document opened by Java: Analyze Stack Trace.
  • Open .log files matching **/*.log, including external logs outside the workspace root while a Java workspace is active.

The extension only scans documents the user opens; it does not search the filesystem. Other plaintext files remain excluded.

Each provider invocation:

  • Scans at most 10,000 lines and 1,000,000 characters.
  • Skips individual lines longer than 1,000 characters.
  • Produces at most 2,000 links.
  • Honors cancellation requests.

Command-link arguments are validated before backend resolution, line numbers must be positive safe integers, and resolved source URIs are restricted to the expected file and jdt schemes.

Demo

linkfy.mp4

Add a DocumentLinkProvider that makes Java stack frames clickable in untitled documents and .log files, so a trace pasted from a log/CI/bug report can be navigated to source without an active debug session. Reuses the session-independent resolveSourceUri backend; frames are resolved lazily on click, with a source-scheme allowlist and length/ReDoS guards. Also adds an optional 'Java: Analyze Stack Trace' command that opens a scratch document prefilled from the clipboard.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

… usage

Add three content-free telemetry events (with __GDPR__ annotations) forming an adoption funnel: provideJavaStackTraceLinks (reach, deduped once per document), navigateToJavaStackFrame (click engagement, with documentSource + resolution outcome), and analyzeJavaStackTrace (command entry usage, with prefilledFromClipboard). All dimensions are categorical; the pasted trace text is never recorded. Also bound clipboard scanning length.
…events

Simplify to one usage signal (navigateToJavaStackFrame with a documentSource dimension), mirroring the existing handleJavaTerminalLink pattern. Drop the per-document reach event (and its WeakSet) and the manual command event - command invocations are already auto-instrumented by instrumentOperationAsVsCodeCommand.
…ault

Add workspaceContains:**/*.java so the passive DocumentLinkProvider is registered as soon as a Java project is opened - without waiting for the user to open a .java file or run a command. This matches exactly the scope where resolveSourceUri can resolve frames to source, so the feature is automatic wherever it can deliver value.
Frame resolution (resolveSourceUri) requires a fully-loaded workspace, so registering the document link provider before jdtls is ready produces links that cannot resolve. Defer provider registration until ServerMode.STANDARD via redhat.java's onDidServerModeChange, mirroring initializeCodeLensProvider. Commands stay registered immediately.
…lick count

The single navigateToJavaStackFrame event is enough to measure adoption; the documentSource breakdown is not needed. Remove the dimension, the IStackFrameLinkArgs field, and the categorizeDocumentSource helper.
Drop the `log` language and `**/*.log` selectors so linkification only
targets pasted traces in untitled (scratch) documents. A `.log` opened
without a Java project can't resolve frames anyway, so scanning them (or
every plaintext file) adds no value. Keeps the feature narrow to the two
intended paste flows: a new tab and the Analyze Stack Trace command.

Copilot-Session: d80e7a97-119d-4f89-a02a-be25b076e806
…rden navigate

- Add a commandPalette when-clause (javaLSReady) to java.debug.analyzeStackTrace
  so it only shows once the Java language server is ready - matching where the
  linkify provider actually registers, and avoiding a dead-end scratch doc in
  non-Java windows.
- Extract the duplicated frame regex + parsing into stackFrameParser.ts, shared
  by the terminal and document link providers so matching stays identical. The
  helper builds a fresh RegExp per call, preserving the terminal provider's
  no-shared-stateful-RegExp contract.
- Wrap resolveSourceUri/navigation in navigateToStackFrame in try/catch (and
  await the navigation) so a not-ready/restarting language server can't surface
  an unhandled rejection.

Copilot-Session: d80e7a97-119d-4f89-a02a-be25b076e806

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new editor surface for Java stack trace navigation by linkifying stack frames in untitled (scratch) documents, reusing the existing resolveSourceUri backend used by terminal linkification.

Changes:

  • Refactors terminal stack-frame matching to use a shared parseJavaStackFrame helper.
  • Introduces an untitled-document DocumentLinkProvider plus commands to analyze/navigate stack traces, with registration deferred until the Java language server reaches Standard mode.
  • Updates extension activation and command contributions to surface Java: Analyze Stack Trace and activate on Java workspaces.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/terminalLinkProvider.ts Reuses shared stack frame parsing for terminal linkification.
src/stackTraceLinkProvider.ts Adds untitled-document linkification + commands for stack-trace navigation and optional scratch-doc creation.
src/stackFrameParser.ts Introduces a shared Java stack frame parser used by both terminal and document providers.
src/extension.ts Wires stack-trace link provider registration into extension activation.
package.json Activates earlier on Java workspaces and contributes the new command + palette visibility gating.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/stackTraceLinkProvider.ts Outdated
Comment thread src/stackTraceLinkProvider.ts Outdated
Comment thread src/stackFrameParser.ts
Cap clipboard prefill content, clarify command registration readiness, and add regression coverage for shared stack frame parsing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780
@wenytang-ms
wenytang-ms requested a review from Copilot July 23, 2026 02:40
@wenytang-ms
wenytang-ms marked this pull request as ready for review July 23, 2026 02:41
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@wenytang-ms

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/stackTraceLinkProvider.ts
Comment thread src/stackTraceLinkProvider.ts Outdated
Encode command URI arguments as an array and validate navigation command inputs before resolving source locations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread src/stackTraceLinkProvider.ts
Comment thread src/stackFrameParser.ts
Use local values for command argument narrowing and make the parser example reflect its required leading whitespace.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread src/stackFrameParser.ts
Validate parsed line numbers centrally so all stack trace link surfaces reject non-positive and unsafe values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread src/stackTraceLinkProvider.ts Outdated
Comment thread src/stackTraceLinkProvider.ts
wenytang-ms and others added 2 commits July 23, 2026 13:01
Defer clipboard parsing to the bounded document link provider and dispose the one-shot server mode listener after registration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780
Preserve complete clipboard content and bound document link scans by total characters and lines so saved log files can be handled safely.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e50dc26-84c4-4532-a7d3-88f6fe016780

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/stackTraceLinkProvider.ts:162

  • analyzeStackTrace inserts the full clipboard text into an untitled document. Very large clipboards can create huge in-memory documents and can noticeably impact VS Code responsiveness even though link scanning is later bounded. Consider capping the inserted text to the same size budget used by the link provider (or prompting before opening a very large document).
    const clipboardContent = await env.clipboard.readText();
    const document = await workspace.openTextDocument({ language: "log", content: clipboardContent });
    await window.showTextDocument(document);

Comment thread src/stackTraceLinkProvider.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/stackTraceLinkProvider.ts:46

  • isStackFrameLinkArgs narrows args to object, but then accesses args.stackTrace / args.methodName / args.lineNumber directly. In TypeScript, object does not allow property access, so this is likely a compile-time error (or forces unsafe typing). Narrow to a Record<string, unknown> (or use a type assertion) before reading properties.
function isStackFrameLinkArgs(args: unknown): args is IStackFrameLinkArgs {
    if (typeof args !== "object" || args === null) {
        return false;
    }

    const stackTrace = "stackTrace" in args ? args.stackTrace : undefined;
    const methodName = "methodName" in args ? args.methodName : undefined;
    const lineNumber = "lineNumber" in args ? args.lineNumber : undefined;
    if (typeof stackTrace !== "string" || typeof methodName !== "string" || typeof lineNumber !== "number"

@wenytang-ms

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@wenytang-ms
wenytang-ms merged commit 9551173 into main Jul 23, 2026
10 checks passed
@wenytang-ms
wenytang-ms deleted the feature/stacktrace-console-1654 branch July 23, 2026 08:06
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.

[Feature Request] Standalone "Java Stack Trace Console" (paste-and-navigate stack traces, independent of an active debug session)

3 participants