1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/* 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 {
formatDisplayName,
} = require("resource://devtools/server/actors/frame.js");
const {
TYPES,
getResourceWatcher,
} = require("resource://devtools/server/actors/resources/index.js");
// Get a string message to display when a frame evaluation throws.
function getThrownMessage(completion) {
try {
if (completion.throw.getOwnPropertyDescriptor) {
return completion.throw.getOwnPropertyDescriptor("message").value;
} else if (completion.toString) {
return completion.toString();
}
} catch (ex) {
// ignore
}
return "Unknown exception";
}
module.exports.getThrownMessage = getThrownMessage;
function logEvent({ threadActor, frame, level, expression, bindings }) {
const {
sourceActor,
line,
column,
} = threadActor.sourcesManager.getFrameLocation(frame);
const displayName = formatDisplayName(frame);
// TODO remove this branch when (#1592584) lands (#1609540)
if (isWorker) {
threadActor._parent._consoleActor.evaluateJS({
text: `console.log(...${expression})`,
bindings: { displayName, ...bindings },
url: sourceActor.url,
lineNumber: line,
});
return undefined;
}
const completion = frame.evalWithBindings(
expression,
{
displayName,
...bindings,
},
{ hideFromDebugger: true }
);
let value;
if (!completion) {
// The evaluation was killed (possibly by the slow script dialog).
value = ["Evaluation failed"];
} else if ("return" in completion) {
value = completion.return;
} else {
value = [getThrownMessage(completion)];
level = `${level}Error`;
}
if (value && typeof value.unsafeDereference === "function") {
value = value.unsafeDereference();
}
const targetActor = threadActor._parent;
const message = {
filename: sourceActor.url,
lineNumber: line,
columnNumber: column,
arguments: value,
level,
chromeContext:
targetActor.actorID &&
/conn\d+\.parentProcessTarget\d+/.test(targetActor.actorID),
// The 'prepareConsoleMessageForRemote' method in webconsoleActor expects internal source ID,
// thus we can't set sourceId directly to sourceActorID.
sourceId: sourceActor.internalSourceId,
};
// Note that only WindowGlobalTarget actor support resource watcher
// This is still missing for worker and content processes
const consoleMessageWatcher = getResourceWatcher(
targetActor,
TYPES.CONSOLE_MESSAGE
);
if (consoleMessageWatcher) {
consoleMessageWatcher.onLogPoint(message);
} else {
// Bug 1642296: Once we enable ConsoleMessage resource on the server, we should remove onConsoleAPICall
// from the WebConsoleActor, and only support the ConsoleMessageWatcher codepath.
targetActor._consoleActor.onConsoleAPICall(message);
}
return undefined;
}
module.exports.logEvent = logEvent;
|