in src/extension.ts [307:399]
export async function attach(
context: vscode.ExtensionContext, attachUrl?: string, config?: Partial<IUserConfig>, useRetry?: boolean): Promise<void> {
if (!telemetryReporter) {
telemetryReporter = createTelemetryReporter(context);
}
const telemetryProps = { viaConfig: `${!!config}`, withTargetUrl: `${!!attachUrl}` };
const { hostname, port, useHttps, timeout } = getRemoteEndpointSettings(config);
// Get the attach target and keep trying until reaching timeout
const startTime = Date.now();
let responseArray: IRemoteTargetJson[] = [];
let exceptionStack: unknown;
do {
try {
// Keep trying to attach to the list endpoint until timeout
responseArray = await debugCore.utils.retryAsync(
() => getListOfTargets(hostname, port, useHttps),
timeout,
/* intervalDelay=*/ SETTINGS_DEFAULT_ATTACH_INTERVAL) as IRemoteTargetJson[];
} catch (e) {
exceptionStack = e;
}
if (responseArray.length > 0) {
// Try to match the given target with the list of targets we received from the endpoint
let targetWebsocketUrl = '';
if (attachUrl) {
// Match the targets using the edge debug adapter logic
let matchedTargets: debugCore.chromeConnection.ITarget[] | undefined;
try {
matchedTargets = debugCore.chromeUtils.getMatchingTargets(responseArray as unknown as debugCore.chromeConnection.ITarget[], attachUrl);
} catch (e) {
void ErrorReporter.showErrorDialog({
errorCode: ErrorCodes.Error,
title: 'Error while getting a debug connection to the target',
message: e,
});
matchedTargets = undefined;
}
if (matchedTargets && matchedTargets.length > 0 && matchedTargets[0].webSocketDebuggerUrl) {
const actualTarget = fixRemoteWebSocket(hostname, port, matchedTargets[0] as unknown as IRemoteTargetJson);
targetWebsocketUrl = actualTarget.webSocketDebuggerUrl;
} else if (!useRetry) {
void vscode.window.showErrorMessage(`Couldn't attach to ${attachUrl}.`);
}
}
if (targetWebsocketUrl) {
// Auto connect to found target
useRetry = false;
const runtimeConfig = getRuntimeConfig(config);
DevToolsPanel.createOrShow(context, telemetryReporter, targetWebsocketUrl, runtimeConfig);
} else if (useRetry) {
// Wait for a little bit until we retry
await new Promise<void>(resolve => {
setTimeout(() => {
resolve();
}, SETTINGS_DEFAULT_ATTACH_INTERVAL);
});
} else {
// Create the list of items to show with fixed websocket addresses
const items = responseArray.map((i: IRemoteTargetJson) => {
i = fixRemoteWebSocket(hostname, port, i);
return {
description: i.url,
detail: i.webSocketDebuggerUrl,
label: i.title,
} as vscode.QuickPickItem;
});
// Show the target list and allow the user to select one
const selection = await vscode.window.showQuickPick(items);
if (selection && selection.detail) {
const runtimeConfig = getRuntimeConfig(config);
DevToolsPanel.createOrShow(context, telemetryReporter, selection.detail, runtimeConfig);
}
}
}
} while (useRetry && Date.now() - startTime < timeout);
// If there is no response after the timeout then throw an exception (unless for legacy Edge targets which we warned about separately)
if (responseArray.length === 0 && config?.type !== 'edge' && config?.type !== 'msedge') {
void ErrorReporter.showErrorDialog({
errorCode: ErrorCodes.Error,
title: 'Error while fetching list of available targets',
message: exceptionStack || 'No available targets to attach.',
});
telemetryReporter.sendTelemetryEvent('command/attach/error/no_json_array', telemetryProps);
}
}