зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1592535 - Add a column displaying the last frame in the stack trace info if it exists r=Harald,Honza
Differential Revision: https://phabricator.services.mozilla.com/D61423 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
cec9db85d8
Коммит
b974090591
|
@ -2080,10 +2080,10 @@ pref("devtools.netmonitor.panes-search-width", 550);
|
|||
pref("devtools.netmonitor.panes-search-height", 450);
|
||||
pref("devtools.netmonitor.filters", "[\"all\"]");
|
||||
pref("devtools.netmonitor.visibleColumns",
|
||||
"[\"status\",\"method\",\"domain\",\"file\",\"cause\",\"type\",\"transferred\",\"contentSize\",\"waterfall\"]"
|
||||
"[\"status\",\"method\",\"domain\",\"file\",\"cause\",\"initiator\",\"type\",\"transferred\",\"contentSize\",\"waterfall\"]"
|
||||
);
|
||||
pref("devtools.netmonitor.columnsData",
|
||||
'[{"name":"status","minWidth":30,"width":5}, {"name":"method","minWidth":30,"width":5}, {"name":"domain","minWidth":30,"width":10}, {"name":"file","minWidth":30,"width":25}, {"name":"url","minWidth":30,"width":25}, {"name":"cause","minWidth":30,"width":10},{"name":"type","minWidth":30,"width":5},{"name":"transferred","minWidth":30,"width":10},{"name":"contentSize","minWidth":30,"width":5},{"name":"waterfall","minWidth":150,"width":25}]');
|
||||
'[{"name":"status","minWidth":30,"width":5}, {"name":"method","minWidth":30,"width":5}, {"name":"domain","minWidth":30,"width":10}, {"name":"file","minWidth":30,"width":25}, {"name":"url","minWidth":30,"width":25}, {"name":"cause","minWidth":30,"width":10},{"name":"initiator","minWidth":30,"width":25},{"name":"type","minWidth":30,"width":5},{"name":"transferred","minWidth":30,"width":10},{"name":"contentSize","minWidth":30,"width":5},{"name":"waterfall","minWidth":150,"width":25}]');
|
||||
pref("devtools.netmonitor.ws.payload-preview-height", 128);
|
||||
pref("devtools.netmonitor.ws.visibleColumns",
|
||||
'["data", "time"]'
|
||||
|
|
|
@ -576,6 +576,10 @@ netmonitor.toolbar.remoteip=Remote IP
|
|||
# in the network table toolbar, above the "cause" column.
|
||||
netmonitor.toolbar.cause=Cause
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.toolbar.initiator): This is the label displayed
|
||||
# in the network table toolbar, above the "initiator" column.
|
||||
netmonitor.toolbar.initiator=Initiator
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.toolbar.type): This is the label displayed
|
||||
# in the network table toolbar, above the "type" column.
|
||||
netmonitor.toolbar.type=Type
|
||||
|
|
|
@ -510,6 +510,54 @@
|
|||
outline: none;
|
||||
}
|
||||
|
||||
.theme-light {
|
||||
--network-initiator-line-color: var(--theme-highlight-blue);
|
||||
--network-initiator-color: var(--theme-highlight-purple);
|
||||
}
|
||||
|
||||
.theme-dark {
|
||||
--network-initiator-line-color: hsl(210, 40%, 60%);
|
||||
--network-initiator-color: var(--blue-40);
|
||||
}
|
||||
|
||||
.requests-list-initiator {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.requests-list-initiator:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.requests-list-initiator-lastframe {
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.request-list-item .requests-list-initiator-filename {
|
||||
cursor: pointer;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.request-list-item:not(.selected) .requests-list-initiator-filename {
|
||||
color: var(--network-initiator-color);
|
||||
}
|
||||
|
||||
.request-list-item.selected .requests-list-initiator-filename {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.request-list-item .requests-list-initiator-line {
|
||||
cursor: pointer;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.request-list-item:not(selected) .requests-list-initiator-line {
|
||||
color: var(--network-initiator-line-color);
|
||||
}
|
||||
|
||||
.request-list-item.selected .requests-list-initiator-line {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Responsive web design support */
|
||||
|
||||
@media (max-width: 700px) {
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const {
|
||||
getUrlBaseName,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
class RequestListColumnInitiator extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
item: PropTypes.object.isRequired,
|
||||
onInitiatorBadgeMouseDown: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return this.props.item.cause !== nextProps.item.cause;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
item: { cause },
|
||||
onInitiatorBadgeMouseDown,
|
||||
} = this.props;
|
||||
|
||||
let initiator = "";
|
||||
let lineNumber = "";
|
||||
if (cause && cause.lastFrame) {
|
||||
const { filename, lineNumber: _lineNumber } = cause.lastFrame;
|
||||
initiator = getUrlBaseName(filename);
|
||||
lineNumber = ":" + _lineNumber;
|
||||
}
|
||||
|
||||
return dom.td(
|
||||
{
|
||||
className: "requests-list-column requests-list-initiator",
|
||||
onMouseDown: onInitiatorBadgeMouseDown,
|
||||
},
|
||||
dom.div(
|
||||
{ className: "requests-list-initiator-lastframe" },
|
||||
dom.span({ className: "requests-list-initiator-filename" }, initiator),
|
||||
dom.span({ className: "requests-list-initiator-line" }, lineNumber)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RequestListColumnInitiator;
|
|
@ -82,6 +82,7 @@ class RequestListContent extends Component {
|
|||
firstRequestStartedMs: PropTypes.number.isRequired,
|
||||
fromCache: PropTypes.bool,
|
||||
onCauseBadgeMouseDown: PropTypes.func.isRequired,
|
||||
onInitiatorBadgeMouseDown: PropTypes.func.isRequired,
|
||||
onItemRightMouseButtonDown: PropTypes.func.isRequired,
|
||||
onItemMouseDown: PropTypes.func.isRequired,
|
||||
onSecurityIconMouseDown: PropTypes.func.isRequired,
|
||||
|
@ -318,6 +319,7 @@ class RequestListContent extends Component {
|
|||
displayedRequests,
|
||||
firstRequestStartedMs,
|
||||
onCauseBadgeMouseDown,
|
||||
onInitiatorBadgeMouseDown,
|
||||
onSecurityIconMouseDown,
|
||||
onWaterfallMouseDown,
|
||||
requestFilterTypes,
|
||||
|
@ -367,6 +369,8 @@ class RequestListContent extends Component {
|
|||
onMouseDown: evt =>
|
||||
this.onMouseDown(evt, item.id, item.channelId),
|
||||
onCauseBadgeMouseDown: () => onCauseBadgeMouseDown(item.cause),
|
||||
onInitiatorBadgeMouseDown: () =>
|
||||
onInitiatorBadgeMouseDown(item.cause),
|
||||
onSecurityIconMouseDown: () =>
|
||||
onSecurityIconMouseDown(item.securityState),
|
||||
onWaterfallMouseDown: () => onWaterfallMouseDown(),
|
||||
|
@ -424,6 +428,11 @@ module.exports = connect(
|
|||
dispatch(Actions.selectDetailsPanelTab("stack-trace"));
|
||||
}
|
||||
},
|
||||
onInitiatorBadgeMouseDown: cause => {
|
||||
if (cause.lastFrame) {
|
||||
dispatch(Actions.selectDetailsPanelTab("stack-trace"));
|
||||
}
|
||||
},
|
||||
selectRequest: (id, channelId) =>
|
||||
dispatch(Actions.selectRequest(id, channelId)),
|
||||
onItemRightMouseButtonDown: id => dispatch(Actions.rightClickRequest(id)),
|
||||
|
|
|
@ -20,6 +20,7 @@ const {
|
|||
|
||||
// Components
|
||||
/* global
|
||||
RequestListColumnInitiator,
|
||||
RequestListColumnCause,
|
||||
RequestListColumnContentSize,
|
||||
RequestListColumnCookies,
|
||||
|
@ -38,7 +39,11 @@ const {
|
|||
RequestListColumnUrl,
|
||||
RequestListColumnWaterfall
|
||||
*/
|
||||
|
||||
loader.lazyGetter(this, "RequestListColumnInitiator", function() {
|
||||
return createFactory(
|
||||
require("devtools/client/netmonitor/src/components/request-list/RequestListColumnInitiator")
|
||||
);
|
||||
});
|
||||
loader.lazyGetter(this, "RequestListColumnCause", function() {
|
||||
return createFactory(
|
||||
require("devtools/client/netmonitor/src/components/request-list/RequestListColumnCause")
|
||||
|
@ -191,6 +196,11 @@ const COLUMN_COMPONENTS = [
|
|||
ColumnComponent: RequestListColumnCause,
|
||||
props: ["onCauseBadgeMouseDown"],
|
||||
},
|
||||
{
|
||||
column: "initiator",
|
||||
ColumnComponent: RequestListColumnInitiator,
|
||||
props: ["onInitiatorBadgeMouseDown"],
|
||||
},
|
||||
{ column: "type", ColumnComponent: RequestListColumnType },
|
||||
{
|
||||
column: "cookies",
|
||||
|
|
|
@ -9,6 +9,7 @@ DevToolsModules(
|
|||
'RequestListColumnCookies.js',
|
||||
'RequestListColumnDomain.js',
|
||||
'RequestListColumnFile.js',
|
||||
'RequestListColumnInitiator.js',
|
||||
'RequestListColumnMethod.js',
|
||||
'RequestListColumnProtocol.js',
|
||||
'RequestListColumnRemoteIP.js',
|
||||
|
|
|
@ -264,6 +264,10 @@ const HEADERS = [
|
|||
name: "cause",
|
||||
canFilter: true,
|
||||
},
|
||||
{
|
||||
name: "initiator",
|
||||
canFilter: true,
|
||||
},
|
||||
{
|
||||
name: "type",
|
||||
canFilter: false,
|
||||
|
|
|
@ -37,6 +37,7 @@ const cols = {
|
|||
scheme: false,
|
||||
remoteip: false,
|
||||
cause: true,
|
||||
initiator: true,
|
||||
type: true,
|
||||
cookies: false,
|
||||
setCookies: false,
|
||||
|
|
|
@ -38,6 +38,9 @@ const {
|
|||
getFormattedIPAndPort,
|
||||
} = require("devtools/client/netmonitor/src/utils/format-utils");
|
||||
const { getUnicodeUrl } = require("devtools/client/shared/unicode-url");
|
||||
const {
|
||||
getUrlBaseName,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
|
||||
/*
|
||||
The function `parseFilters` is from:
|
||||
|
@ -166,6 +169,16 @@ function isFlagFilterMatch(item, { type, value, negative }) {
|
|||
? causeType.toLowerCase().includes(value)
|
||||
: false;
|
||||
},
|
||||
initiator: () => {
|
||||
const initiator = item.cause.lastFrame
|
||||
? getUrlBaseName(item.cause.lastFrame.filename) +
|
||||
":" +
|
||||
item.cause.lastFrame.lineNumber
|
||||
: "";
|
||||
return typeof initiator === "string"
|
||||
? initiator.toLowerCase().includes(value)
|
||||
: !value;
|
||||
},
|
||||
transferred: () => {
|
||||
if (item.fromCache) {
|
||||
return false;
|
||||
|
|
|
@ -15,6 +15,9 @@ const {
|
|||
const {
|
||||
RESPONSE_HEADERS,
|
||||
} = require("devtools/client/netmonitor/src/constants");
|
||||
const {
|
||||
getUrlBaseName,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
|
||||
/**
|
||||
* Predicates used when sorting items.
|
||||
|
@ -167,6 +170,31 @@ function cause(first, second) {
|
|||
return result || waterfall(first, second);
|
||||
}
|
||||
|
||||
function initiator(first, second) {
|
||||
let firstInitiator = "";
|
||||
let firstInitiatorLineNumber = 0;
|
||||
|
||||
if (first.cause.lastFrame) {
|
||||
firstInitiator = getUrlBaseName(first.cause.lastFrame.filename);
|
||||
firstInitiatorLineNumber = first.cause.lastFrame.lineNumber;
|
||||
}
|
||||
|
||||
let secondInitiator = "";
|
||||
let secondInitiatorLineNumber = 0;
|
||||
|
||||
if (second.cause.lastFrame) {
|
||||
secondInitiator = getUrlBaseName(second.cause.lastFrame.filename);
|
||||
secondInitiatorLineNumber = second.cause.lastFrame.lineNumber;
|
||||
}
|
||||
|
||||
let result = compareValues(firstInitiator, secondInitiator);
|
||||
if (result === 0) {
|
||||
result = compareValues(firstInitiatorLineNumber, secondInitiatorLineNumber);
|
||||
}
|
||||
|
||||
return result || waterfall(first, second);
|
||||
}
|
||||
|
||||
function setCookies(first, second) {
|
||||
let { responseCookies: firstResponseCookies = { cookies: [] } } = first;
|
||||
let { responseCookies: secondResponseCookies = { cookies: [] } } = second;
|
||||
|
@ -255,6 +283,7 @@ const sorters = {
|
|||
setCookies,
|
||||
remoteip,
|
||||
cause,
|
||||
initiator,
|
||||
type,
|
||||
transferred,
|
||||
contentSize,
|
||||
|
|
|
@ -156,6 +156,7 @@ skip-if = verify # Bug 1607678
|
|||
[browser_net_headers_sorted.js]
|
||||
[browser_net_headers-resize.js]
|
||||
[browser_net_image-tooltip.js]
|
||||
[browser_net_initiator.js]
|
||||
[browser_net_json-b64.js]
|
||||
[browser_net_json-empty.js]
|
||||
[browser_net_json-null.js]
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
const {
|
||||
getUrlBaseName,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
/**
|
||||
* Tests if request initiator is reported correctly.
|
||||
*/
|
||||
|
||||
const INITIATOR_FILE_NAME = "html_cause-test-page.html";
|
||||
const INITIATOR_URL = EXAMPLE_URL + INITIATOR_FILE_NAME;
|
||||
|
||||
const EXPECTED_REQUESTS = [
|
||||
{
|
||||
method: "GET",
|
||||
url: INITIATOR_URL,
|
||||
causeType: "document",
|
||||
causeUri: null,
|
||||
stack: false,
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "stylesheet_request",
|
||||
causeType: "stylesheet",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: false,
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "img_request",
|
||||
causeType: "img",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: false,
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "xhr_request",
|
||||
causeType: "xhr",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: [
|
||||
{ fn: "performXhrRequestCallback", file: INITIATOR_FILE_NAME, line: 26 },
|
||||
],
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "fetch_request",
|
||||
causeType: "fetch",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: [{ fn: "performFetchRequest", file: INITIATOR_FILE_NAME, line: 31 }],
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "promise_fetch_request",
|
||||
causeType: "fetch",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: [
|
||||
{
|
||||
fn: "performPromiseFetchRequestCallback",
|
||||
file: INITIATOR_FILE_NAME,
|
||||
line: 37,
|
||||
},
|
||||
{
|
||||
fn: "performPromiseFetchRequest",
|
||||
file: INITIATOR_FILE_NAME,
|
||||
line: 36,
|
||||
asyncCause: "promise callback",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
url: EXAMPLE_URL + "timeout_fetch_request",
|
||||
causeType: "fetch",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: [
|
||||
{
|
||||
fn: "performTimeoutFetchRequestCallback2",
|
||||
file: INITIATOR_FILE_NAME,
|
||||
line: 44,
|
||||
},
|
||||
{
|
||||
fn: "performTimeoutFetchRequestCallback1",
|
||||
file: INITIATOR_FILE_NAME,
|
||||
line: 43,
|
||||
asyncCause: "setTimeout handler",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
method: "POST",
|
||||
url: EXAMPLE_URL + "beacon_request",
|
||||
causeType: "beacon",
|
||||
causeUri: INITIATOR_URL,
|
||||
stack: [
|
||||
{ fn: "performBeaconRequest", file: INITIATOR_FILE_NAME, line: 50 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function() {
|
||||
// Async stacks aren't on by default in all builds
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["javascript.options.asyncstack", true]],
|
||||
});
|
||||
|
||||
// the initNetMonitor function clears the network request list after the
|
||||
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
|
||||
// and only then load the real thing from INITIATOR_URL - we want to catch
|
||||
// all the requests the page is making, not only the XHRs.
|
||||
// We can't use about:blank here, because initNetMonitor checks that the
|
||||
// page has actually made at least one request.
|
||||
const { tab, monitor } = await initNetMonitor(SIMPLE_URL);
|
||||
|
||||
const { document, store, windowRequire } = monitor.panelWin;
|
||||
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
const { getSortedRequests } = windowRequire(
|
||||
"devtools/client/netmonitor/src/selectors/index"
|
||||
);
|
||||
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
const wait = waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
|
||||
BrowserTestUtils.loadURI(tab.linkedBrowser, INITIATOR_URL);
|
||||
await wait;
|
||||
|
||||
// For all expected requests
|
||||
for (const [index, { stack }] of EXPECTED_REQUESTS.entries()) {
|
||||
if (!stack) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item .requests-list-initiator")[
|
||||
index
|
||||
]
|
||||
);
|
||||
|
||||
// Clicking on the initiator column should open the Stack Trace panel
|
||||
const onStackTraceRendered = waitUntil(() =>
|
||||
document.querySelector("#stack-trace-panel .stack-trace .frame-link")
|
||||
);
|
||||
await onStackTraceRendered;
|
||||
}
|
||||
|
||||
is(
|
||||
store.getState().requests.requests.length,
|
||||
EXPECTED_REQUESTS.length,
|
||||
"All the page events should be recorded."
|
||||
);
|
||||
|
||||
validateRequests(EXPECTED_REQUESTS, monitor);
|
||||
|
||||
// Sort the requests by initiator and check the order
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "click" },
|
||||
document.querySelector("#requests-list-initiator-button")
|
||||
);
|
||||
const expectedOrder = EXPECTED_REQUESTS.map(r => {
|
||||
if (r.stack) {
|
||||
const { file, line } = r.stack[0];
|
||||
return getUrlBaseName(file) + ":" + line;
|
||||
}
|
||||
return "";
|
||||
}).sort();
|
||||
expectedOrder.forEach((expectedInitiator, i) => {
|
||||
const request = getSortedRequests(store.getState())[i];
|
||||
if (request.cause.stacktraceAvailable) {
|
||||
const { fileName, lineNumber } = request.cause.lastFrame;
|
||||
const initiator = getUrlBaseName(fileName) + ":" + lineNumber;
|
||||
is(
|
||||
initiator,
|
||||
expectedInitiator,
|
||||
`The request #${i} has the expected initiator after sorting`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
await teardown(monitor);
|
||||
});
|
|
@ -143,7 +143,7 @@ const gDefaultFilters = Services.prefs.getCharPref(
|
|||
// Reveal many columns for test
|
||||
Services.prefs.setCharPref(
|
||||
"devtools.netmonitor.visibleColumns",
|
||||
'["cause","contentSize","cookies","domain","duration",' +
|
||||
'["cause","initiator","contentSize","cookies","domain","duration",' +
|
||||
'"endTime","file","url","latency","method","protocol",' +
|
||||
'"remoteip","responseTime","scheme","setCookies",' +
|
||||
'"startTime","status","transferred","type","waterfall"]'
|
||||
|
@ -157,6 +157,7 @@ Services.prefs.setCharPref(
|
|||
'{"name":"file","minWidth":30,"width":25},' +
|
||||
'{"name":"url","minWidth":30,"width":25},' +
|
||||
'{"name":"cause","minWidth":30,"width":10},' +
|
||||
'{"name":"initiator","minWidth":30,"width":25},' +
|
||||
'{"name":"type","minWidth":30,"width":5},' +
|
||||
'{"name":"transferred","minWidth":30,"width":10},' +
|
||||
'{"name":"contentSize","minWidth":30,"width":5},' +
|
||||
|
|
|
@ -58,6 +58,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
this.observer.init();
|
||||
|
||||
this.stackTraces = new Set();
|
||||
this.lastFrames = new Map();
|
||||
|
||||
this.onStackTraceAvailable = this.onStackTraceAvailable.bind(this);
|
||||
this.onRequestContent = this.onRequestContent.bind(this);
|
||||
|
@ -156,6 +157,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
}
|
||||
|
||||
this.stackTraces.clear();
|
||||
this.lastFrames.clear();
|
||||
if (this.messageManager) {
|
||||
this.stopListening();
|
||||
this.messageManager = null;
|
||||
|
@ -170,14 +172,19 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
this.stopListening();
|
||||
this.messageManager = mm;
|
||||
this.stackTraces = new Set();
|
||||
this.lastFrames.clear();
|
||||
this.startListening();
|
||||
},
|
||||
|
||||
onStackTraceAvailable(msg) {
|
||||
const { channelId } = msg.data;
|
||||
if (!msg.data.stacktrace) {
|
||||
this.lastFrames.delete(channelId);
|
||||
this.stackTraces.delete(channelId);
|
||||
} else {
|
||||
if (msg.data.lastFrame) {
|
||||
this.lastFrames.set(channelId, msg.data.lastFrame);
|
||||
}
|
||||
this.stackTraces.add(channelId);
|
||||
}
|
||||
},
|
||||
|
@ -300,6 +307,10 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
|
|||
if (event.cause.stacktrace) {
|
||||
this.stackTraces.delete(id);
|
||||
}
|
||||
if (this.lastFrames.has(id)) {
|
||||
event.cause.lastFrame = this.lastFrames.get(id);
|
||||
this.lastFrames.delete(id);
|
||||
}
|
||||
actor.init(event);
|
||||
|
||||
this._networkEventActorsByURL.set(actor._request.url, actor);
|
||||
|
|
|
@ -71,6 +71,8 @@ StackTraceCollector.prototype = {
|
|||
messageManager.sendAsyncMessage("debug:request-stack-available", {
|
||||
channelId: id,
|
||||
stacktrace: stacktrace && stacktrace.length > 0,
|
||||
lastFrame:
|
||||
stacktrace && stacktrace.length > 0 ? stacktrace[0] : undefined,
|
||||
});
|
||||
}
|
||||
this.stacktracesById.set(id, stacktrace);
|
||||
|
|
Загрузка…
Ссылка в новой задаче