Skip to content

Function Host Debugger View#4883

Merged
nturinski merged 62 commits into
mainfrom
nat/debuggerView
Mar 26, 2026
Merged

Function Host Debugger View#4883
nturinski merged 62 commits into
mainfrom
nat/debuggerView

Conversation

@nturinski

Copy link
Copy Markdown
Member

This PR adds a Function Host Debug view to the Azure Functions extension. The view appears in the Run and Debug panel and lists running Function Host tasks along with their recent error output.

A new tree view provider backs this view and supplies nodes for active hosts and error entries. The view includes commands to refresh the data, clear recorded errors, view or copy recent logs, and send an error to Copilot. These commands are available from the view toolbar and node context menus.

The PR also introduces a setting to always show the Function Host Debug view, regardless of context.

Supporting changes include exporting shared utilities for identifying host error logs and cleaning log output, extending command handling to accept argument arrays, and updating the Functions task provider to allow additional CLI arguments in task definitions.

No host running (only visible if always show setting is enabled)
image

Function host running with no errors
image

Function host running with an error
image

Location of Ask Copilot context menu
image

nturinski and others added 30 commits October 24, 2025 10:55
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Nathan Turinski and others added 2 commits March 11, 2026 17:06
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@nturinski

Copy link
Copy Markdown
Member Author

@copilot Do another PR review

Copilot AI commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

@nturinski I've opened a new pull request, #4928, to work on those changes. Once the pull request is ready, I'll request review from you.

Comment thread src/funcCoreTools/funcHostTask.ts Outdated
const taskDirectory = taskExecution.options?.cwd?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path);
buildPath = buildPath?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path);
return taskDirectory && buildPath && normalizePath(taskDirectory) === normalizePath(buildPath);
const resolvedBuildPath = buildPath?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

task.scope can be a TaskScope enum value (just a number), not only a WorkspaceFolder. Casting it here without checking means .uri?.path evaluates to undefined, and String.replace() will happily coerce that to the literal string "undefined" — so you'd end up with paths like /some/path/undefined/sub instead of the original unresolved string.

We already do the right typeof check in registerFunctionHostDebugView.ts, so maybe something like:

const workspacePath = typeof t.taskExecution.task?.scope === 'object'
    ? (t.taskExecution.task.scope as vscode.WorkspaceFolder).uri?.path
    : undefined;
const taskDirectory = workspacePath
    ? taskExecution.options?.cwd?.replace('${workspaceFolder}', workspacePath)
    : taskExecution.options?.cwd;
const resolvedBuildPath = workspacePath
    ? buildPath?.replace('${workspaceFolder}', workspacePath)
    : buildPath;

Comment on lines +109 to +113
const funcTaskStartedEmitter = new vscode.EventEmitter<{ scope: vscode.WorkspaceFolder | vscode.TaskScope, execution?: vscode.ShellExecution }>();
export const onFuncTaskStarted = funcTaskStartedEmitter.event;

const runningFuncTasksChangedEmitter = new vscode.EventEmitter<void>();
export const onRunningFuncTasksChanged = runningFuncTasksChangedEmitter.event;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

these emitters are never disposed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, the issue is that we need to create them when the extension is activated, and if we dispose them after a function host task is terminated, they never get instantiated again.

I went ahead and disposed them on deactivation, which I think should happen anyway, but just to be explicit.

@MicroFish91

MicroFish91 commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

I'm still getting the issue where the Functions Host Debugger view appears for a second and then immediately disappears (hides) after hitting F5, does this repro for anyone else?

@nturinski

Copy link
Copy Markdown
Member Author

I'm still getting the issue where the Functions Host Debugger view appears for a second and then immediately disappears (hides) after hitting F5, does this repro for anyone else?

In light of this issue, I did the following:

Debugger View is always visible, but it collapsed by default.
Debugger View gets focused if the user is debugging and the function host has an error.
It only gets focused on the FIRST error.

@MicroFish91

MicroFish91 commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Is there much of a difference between "clear function host errors" and "clear stopped sessions"? I'm wondering if we can get rid of the first one if they end up roughly doing the same since (assuming what gets populated here are errors by default).

@MicroFish91 MicroFish91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe a future todo, but consider splitting up the getChildren methods for each tree item out into their own class logic so that there is less code intersection in the tree data provider's get children method

@nturinski

nturinski commented Mar 26, 2026

Copy link
Copy Markdown
Member Author

Is there much of a difference between "clear function host errors" and "clear stopped sessions"? I'm wondering if we can get rid of the first one if they end up roughly doing the same since (assuming what gets populated here are errors by default).

In practice, probably not. My initial thought was you may want to clear just the errors during a live session, but keep the old sessions? I'm not sure how realistic that is. At the very least, they don't need to both be ribbon buttons.

@nturinski nturinski merged commit a92c62f into main Mar 26, 2026
2 of 3 checks passed
@nturinski nturinski deleted the nat/debuggerView branch March 26, 2026 18:12
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.

6 participants