Skip to content

Commit d5e9aa0

Browse files
authored
Ensure tasks are resolved when run from extension host (#101904)
Related to #101884
1 parent 49b121d commit d5e9aa0

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

src/vs/workbench/api/browser/mainThreadTask.ts

+37-10
Original file line numberDiff line numberDiff line change
@@ -534,20 +534,47 @@ export class MainThreadTask implements MainThreadTaskShape {
534534
}
535535
}
536536

537-
public $executeTask(value: TaskDTO): Promise<TaskExecutionDTO> {
537+
// Passing in a TaskHandleDTO will cause the task to get re-resolved, which is important for tasks are coming from the core,
538+
// such as those gotten from a fetchTasks, since they can have missing configuration properties.
539+
public $executeTask(value: TaskHandleDTO | TaskDTO): Promise<TaskExecutionDTO> {
538540
return new Promise<TaskExecutionDTO>((resolve, reject) => {
539-
const task = TaskDTO.to(value, this._workspaceContextServer, true)!;
540-
this._taskService.run(task).then(undefined, reason => {
541-
// eat the error, it has already been surfaced to the user and we don't care about it here
542-
});
543-
const result: TaskExecutionDTO = {
544-
id: task._id,
545-
task: TaskDTO.from(task)
546-
};
547-
resolve(result);
541+
if (TaskHandleDTO.is(value)) {
542+
const workspaceFolder = typeof value.workspaceFolder === 'string' ? value.workspaceFolder : this._workspaceContextServer.getWorkspaceFolder(URI.revive(value.workspaceFolder));
543+
if (workspaceFolder) {
544+
this._taskService.getTask(workspaceFolder, value.id, true).then((task: Task | undefined) => {
545+
if (!task) {
546+
reject(new Error('Task not found'));
547+
} else {
548+
this._taskService.run(task).then(undefined, reason => {
549+
// eat the error, it has already been surfaced to the user and we don't care about it here
550+
});
551+
const result: TaskExecutionDTO = {
552+
id: value.id,
553+
task: TaskDTO.from(task)
554+
};
555+
resolve(result);
556+
}
557+
}, (_error) => {
558+
reject(new Error('Task not found'));
559+
});
560+
} else {
561+
reject(new Error('No workspace folder'));
562+
}
563+
} else {
564+
const task = TaskDTO.to(value, this._workspaceContextServer, true)!;
565+
this._taskService.run(task).then(undefined, reason => {
566+
// eat the error, it has already been surfaced to the user and we don't care about it here
567+
});
568+
const result: TaskExecutionDTO = {
569+
id: task._id,
570+
task: TaskDTO.from(task)
571+
};
572+
resolve(result);
573+
}
548574
});
549575
}
550576

577+
551578
public $customExecutionComplete(id: string, result?: number): Promise<void> {
552579
return new Promise<void>((resolve, reject) => {
553580
this._taskService.getActiveTasks().then((tasks) => {

src/vs/workbench/api/common/extHost.protocol.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ export interface MainThreadTaskShape extends IDisposable {
780780
$unregisterTaskProvider(handle: number): Promise<void>;
781781
$fetchTasks(filter?: tasks.TaskFilterDTO): Promise<tasks.TaskDTO[]>;
782782
$getTaskExecution(value: tasks.TaskHandleDTO | tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
783-
$executeTask(task: tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
783+
$executeTask(task: tasks.TaskHandleDTO | tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
784784
$terminateTask(id: string): Promise<void>;
785785
$registerTaskSystem(scheme: string, info: tasks.TaskSystemInfoDTO): void;
786786
$customExecutionComplete(id: string, result?: number): Promise<void>;

src/vs/workbench/api/node/extHostTask.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,13 @@ export class ExtHostTask extends ExtHostTaskBase {
5454
// We have a preserved ID. So the task didn't change.
5555
if (tTask._id !== undefined) {
5656
// Always get the task execution first to prevent timing issues when retrieving it later
57-
const executionDTO = await this._proxy.$getTaskExecution(TaskHandleDTO.from(tTask));
57+
const handleDto = TaskHandleDTO.from(tTask);
58+
const executionDTO = await this._proxy.$getTaskExecution(handleDto);
5859
if (executionDTO.task === undefined) {
5960
throw new Error('Task from execution DTO is undefined');
6061
}
6162
const execution = await this.getTaskExecution(executionDTO, task);
62-
this._proxy.$executeTask(executionDTO.task).catch(() => { /* The error here isn't actionable. */ });
63+
this._proxy.$executeTask(handleDto).catch(() => { /* The error here isn't actionable. */ });
6364
return execution;
6465
} else {
6566
const dto = TaskDTO.from(task, extension);

0 commit comments

Comments
 (0)