UNPKG

chrome-devtools-frontend

Version:
160 lines (116 loc) • 5.6 kB
# Utilizing Source Maps in DevTools This document describes how to utilize source maps and translate raw runtime locations into original source locations inside the DevTools frontend. DevTools provides a set of high-level abstractions and UI widgets to parse, symbolize, and render stack traces and errors. Prefer these tools over manual coordinate translation or raw string parsing. --- ## Central Coordinate Translation: DebuggerWorkspaceBinding The `DebuggerWorkspaceBinding` class (located in `front_end/models/bindings/`) acts as the central coordinator for mapping compiled/raw runtime coordinates to workspace/UI locations. It manages various source mappings (such as source maps, compiler mappings, and language plugins). ### Translating Raw Locations To convert a single raw debugger location (with a script ID, line number, and column number) into an original source location, use: ```ts const uiLocation = await DebuggerWorkspaceBinding.instance() .rawLocationToUILocation(rawLocation); ``` Since source maps may need to be loaded or parsed, this method returns a `Promise` resolving to `Workspace.UISourceCode.UILocation | null`. --- ## Structured Stack Trace Abstractions The project organizes stack traces and errors around two primary models: ### 1. StackTrace Located in `front_end/models/stack_trace/`, a `StackTrace` represents a structured stack trace. It is composed of: - **`syncFragment`** (`Fragment`): The synchronous part of the call stack. - **`asyncFragments`** (`AsyncFragment[]`): Asynchronous call stack segments, each with a description (e.g., "Promise.then") and its own frames. Each frame (`Frame`) contains properties like `url`, `uiSourceCode`, `name` (translated name), `rawName` (untranslated name), `line`, `column`, and flags indicating if the frame `isInline`, `isWasm`, or has `missingDebugInfo`. #### Creating a StackTrace `DebuggerWorkspaceBinding` provides several helpers depending on your source format: * **From CDP Protocol Stack Trace**: ```ts const stackTrace = await DebuggerWorkspaceBinding.instance() .createStackTraceFromProtocolRuntime(protocolStackTrace, target); ``` * **From Debugger Pause Event**: ```ts const stackTrace = await DebuggerWorkspaceBinding.instance() .createStackTraceFromDebuggerPaused(pausedDetails, target); ``` * **From an Error-Like Stack String**: ```ts const stackTrace = await DebuggerWorkspaceBinding.instance() .createStackTraceFromErrorStackLikeString(target, stackString, exceptionDetails); ``` --- ### 2. SymbolizedError Located in `front_end/models/bindings/SymbolizedError.ts`, `SymbolizedError` is a union type of `SymbolizedErrorObject` and `UnparsableError`. It represents a fully parsed and symbolized Error object. * **`SymbolizedErrorObject`**: Contains the parsed error message (`message`), the parsed `ParsedErrorStackTrace` (`stackTrace`), and an optional `cause` (`SymbolizedError`), which allows recursive representation of chained errors. It also handles special cases like compile-time or eval-time `SyntaxError`s, exposing a `syntaxErrorLocation` pointing directly to where the parse failed. * **`UnparsableError`**: A fallback representation for stack traces that cannot be structurally parsed. #### Creating a SymbolizedError To resolve a `RemoteObject` (of subtype `error` or type `string`) into a symbolized representation: ```ts const symbolizedError = await DebuggerWorkspaceBinding.instance() .createSymbolizedError(remoteObject, exceptionDetails); ``` > **Memory Management Note:** Both `StackTrace` and `SymbolizedError` models > listen to live location updates and must be properly `dispose()`d when no > longer used to prevent memory leaks. --- ## UI Widgets To render the above models in the DevTools UI, you should use the following pre-built widgets instead of constructing your own custom tables or lists: ### 1. StackTracePreviewContent Located in `front_end/ui/legacy/components/utils/JSPresentationUtils.ts`, this widget renders a structured `StackTrace` inside a shadow DOM. It automatically handles collapsible sections (expanded/collapsed) and ignore-listed files or folders. #### Usage: ```ts import * as Components from '../../ui/legacy/components/utils/utils.js'; import * as Workspace from '../../models/workspace/workspace.js'; const preview = new Components.JSPresentationUtils.StackTracePreviewContent(); preview.stackTrace = stackTrace; preview.options = { expandable: true, showColumnNumber: true, ignoreListManager: Workspace.IgnoreListManager.IgnoreListManager.instance(), }; ``` --- ### 2. SymbolizedErrorWidget Located in `front_end/panels/console/SymbolizedErrorWidget.ts`, this widget is designed to display a complete `SymbolizedError`, including its parsed message, any nested `cause` errors (rendered recursively with "Caused by:"), and links for syntax error locations. #### Usage: ```ts import * as Panels from '../../panels/panels.js'; import * as Workspace from '../../models/workspace/workspace.js'; const errorWidget = new Panels.Console.SymbolizedErrorWidget(); errorWidget.error = symbolizedError; errorWidget.ignoreListManager = Workspace.IgnoreListManager.IgnoreListManager .instance(); ``` --- ## Reaching Out If none of the existing methods, abstractions, or widgets cover your specific use-case, or if you need additional capabilities for coordinate/stack trace symbolization, please **reach out to the DevTools team**. Do not roll your own coordinate mapping or raw string parsing logic.