Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/puppet-chrome/lib/ConsoleMessage.ts
1028 views
1
/**
2
* Copyright 2018 Google Inc. All rights reserved.
3
* Modifications copyright (c) Data Liberation Foundation Inc.
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*/
17
import { Protocol } from 'devtools-protocol';
18
import { DevtoolsSession } from './DevtoolsSession';
19
import ExceptionDetails = Protocol.Runtime.ExceptionDetails;
20
import StackTrace = Protocol.Runtime.StackTrace;
21
import ObjectPreview = Protocol.Runtime.ObjectPreview;
22
import ConsoleAPICalledEvent = Protocol.Runtime.ConsoleAPICalledEvent;
23
24
export default class ConsoleMessage {
25
constructor(readonly message: string, readonly location: string, readonly type: string) {}
26
27
static create(devtoolsSession: DevtoolsSession, event: ConsoleAPICalledEvent) {
28
const { args, stackTrace, type, context } = event;
29
30
const message = args
31
.map(arg => {
32
devtoolsSession.disposeRemoteObject(arg);
33
34
return stringifyRemoteObject(arg);
35
})
36
.join(' ');
37
38
const location = `//#${context ?? 'nocontext'}${this.printStackTrace(stackTrace)}`;
39
return new ConsoleMessage(message, location, type);
40
}
41
42
static exceptionToError(exceptionDetails: ExceptionDetails) {
43
const error = new Error(exceptionDetails.text);
44
if (exceptionDetails.exception) {
45
error.stack = stringifyRemoteObject(exceptionDetails.exception);
46
} else if (exceptionDetails.stackTrace) {
47
error.stack = this.printStackTrace(exceptionDetails.stackTrace);
48
}
49
return error;
50
}
51
52
private static printStackTrace(stackTrace: StackTrace) {
53
let message = '';
54
if (!stackTrace) return message;
55
for (const callframe of stackTrace.callFrames) {
56
const location = `${callframe.url}:${callframe.lineNumber}:${callframe.columnNumber}`;
57
const functionName = callframe.functionName || '<anonymous>';
58
message += `\n at ${functionName} (${location})`;
59
}
60
return message;
61
}
62
}
63
64
function stringifyRemoteObject(remoteObject: Protocol.Runtime.RemoteObject) {
65
if (remoteObject.unserializableValue) {
66
if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined') {
67
return BigInt(remoteObject.unserializableValue.replace('n', ''));
68
}
69
70
switch (remoteObject.unserializableValue) {
71
case '-0':
72
return -0;
73
case 'NaN':
74
return NaN;
75
case 'Infinity':
76
return Infinity;
77
case '-Infinity':
78
return -Infinity;
79
default:
80
throw new Error(`Unsupported unserializable value: ${remoteObject.unserializableValue}`);
81
}
82
}
83
if (remoteObject.type === 'object' && remoteObject.preview) {
84
return JSON.stringify(previewToObject(remoteObject.preview));
85
}
86
return remoteObject.value ?? remoteObject.description;
87
}
88
89
function previewToObject(preview: ObjectPreview) {
90
const subProps = preview.properties.map(
91
prop => `${prop.name}: ${prop.valuePreview ? previewToObject(prop.valuePreview) : prop.value}`,
92
);
93
const props = `{ ${subProps.join(', ')} }`;
94
if (preview.description === 'Object') return props;
95
return `${preview.description}(${props})`;
96
}
97
98