fix(debug): preserve configured dap launch args

This commit is contained in:
DanZAIO
2026-06-19 20:54:38 -03:00
parent 90b7c395f9
commit 23922f3fe2
2 changed files with 23 additions and 2 deletions
+1 -1
View File
@@ -289,7 +289,7 @@ export class DapSessionManager {
...(options.extraLaunchArguments ?? {}),
program: options.program,
cwd: options.cwd,
args: options.args,
...(options.args !== undefined ? { args: options.args } : {}),
};
// Subscribe to stop events BEFORE launching so we don't miss
// stopOnEntry events that arrive before we start listening.
@@ -62,6 +62,7 @@ class FakeDapClient {
readonly #exited = Promise.withResolvers<void>();
readonly #handlers = new Map<string, Set<DapEventHandler>>();
#alive = true;
requests: Array<{ command: string; args: unknown }> = [];
constructor(
readonly adapter: DapResolvedAdapter,
@@ -73,6 +74,7 @@ class FakeDapClient {
attachErrorDelayMs?: number;
configurationDoneError?: string;
rejectStopWaiters?: boolean;
stopAfterLaunch?: boolean;
},
) {
this.proc = {
@@ -95,7 +97,8 @@ class FakeDapClient {
return { supportsConfigurationDoneRequest: true };
}
async sendRequest(command: string): Promise<unknown> {
async sendRequest(command: string, args?: unknown): Promise<unknown> {
this.requests.push({ command, args });
if (command === "launch" && this.options.launchError) {
if (this.options.launchErrorDelayMs) await Bun.sleep(this.options.launchErrorDelayMs);
throw new Error(this.options.launchError);
@@ -107,6 +110,9 @@ class FakeDapClient {
if (command === "configurationDone" && this.options.configurationDoneError) {
throw new Error(this.options.configurationDoneError);
}
if (command === "launch" && this.options.stopAfterLaunch) {
queueMicrotask(() => this.#emit("stopped", { reason: "entry", threadId: 1 }));
}
return {};
}
@@ -158,6 +164,21 @@ afterEach(() => {
});
describe("DAP launch failure handling", () => {
it("preserves adapter launchDefaults args when launch omits args", async () => {
const adapter: DapResolvedAdapter = {
...TEST_ADAPTER,
launchDefaults: { request: "launch", args: ["--configured"], stopOnEntry: true },
};
const manager = new DapSessionManager();
const fake = new FakeDapClient(adapter, process.cwd(), { stopAfterLaunch: true });
spyOn(DapClient, "spawn").mockResolvedValue(fake as unknown as DapClient);
await manager.launch({ adapter, program: "/bin/echo", cwd: process.cwd() }, undefined, 10);
const launch = fake.requests.find(request => request.command === "launch");
expect(launch?.args).toMatchObject({ args: ["--configured"], program: "/bin/echo" });
});
it("surfaces the launch failure when configurationDone also fails", async () => {
const manager = new DapSessionManager();
const fake = new FakeDapClient(TEST_ADAPTER, process.cwd(), {