MCPcopy Create free account
hub / github.com/ChromeDevTools/chrome-devtools-mcp / createStackTrace

Function createStackTrace

src/devtools/DevtoolsUtils.ts:394–445  ·  view source on GitHub ↗
(
  devTools: TargetUniverse,
  rawStackTrace: Protocol.Runtime.StackTrace,
  targetId: string | undefined,
)

Source from the content-addressed store, hash-verified

392}
393
394export async function createStackTrace(
395 devTools: TargetUniverse,
396 rawStackTrace: Protocol.Runtime.StackTrace,
397 targetId: string | undefined,
398): Promise<DevTools.StackTrace.StackTrace.StackTrace> {
399 const targetManager = devTools.universe.context.get(DevTools.TargetManager);
400 const target = targetId
401 ? targetManager.targetById(targetId) || devTools.target
402 : devTools.target;
403 const model = target.model(DevTools.DebuggerModel) as DevTools.DebuggerModel;
404
405 // DevTools doesn't wait for source maps to attach before building a stack trace, rather it'll send
406 // an update event once a source map was attached and the stack trace retranslated. This doesn't
407 // work in the MCP case, so we'll collect all script IDs upfront and wait for any pending source map
408 // loads before creating the stack trace. We might also have to wait for Debugger.ScriptParsed events if
409 // the stack trace is created particularly early.
410 const scriptIds = new Set<Protocol.Runtime.ScriptId>();
411 for (const frame of rawStackTrace.callFrames) {
412 scriptIds.add(frame.scriptId);
413 }
414 for (
415 let asyncStack = rawStackTrace.parent;
416 asyncStack;
417 asyncStack = asyncStack.parent
418 ) {
419 for (const frame of asyncStack.callFrames) {
420 scriptIds.add(frame.scriptId);
421 }
422 }
423
424 const signal = AbortSignal.timeout(1_000);
425 await Promise.all(
426 [...scriptIds].map(id =>
427 waitForScript(model, id, signal)
428 .then(script =>
429 model.sourceMapManager().sourceMapForClientPromise(script),
430 )
431 .catch(),
432 ),
433 );
434
435 const binding = devTools.universe.context.get(
436 DevTools.DebuggerWorkspaceBinding,
437 );
438 // DevTools uses branded types for ScriptId and others. Casting the puppeteer protocol type to the DevTools protocol type is safe.
439 return binding.createStackTraceFromProtocolRuntime(
440 rawStackTrace as Parameters<
441 DevTools.DebuggerWorkspaceBinding['createStackTraceFromProtocolRuntime']
442 >[0],
443 target,
444 );
445}
446
447// Waits indefinitely for the script so pair it with Promise.race.
448async function waitForScript(

Callers 2

fromDetailsMethod · 0.85

Calls 3

waitForScriptFunction · 0.85
getMethod · 0.80
timeoutMethod · 0.80

Tested by

no test coverage detected