53
});
54
}
56
>
static async installFullHandler(accessor: ServicesAccessor): Promise<void> {
57
>
// uses extension knowledges to correlate errors with extensions
58
>
59
>
const logService = accessor.get(ILogService);
60
>
const rpcService = accessor.get(IExtHostRpcService);
61
>
const extensionService = accessor.get(IExtHostExtensionService);
62
>
const extensionTelemetry = accessor.get(IExtHostTelemetry);
63
>
const apiDeprecationService = accessor.get(IExtHostApiDeprecationService);
64
>
65
>
const mainThreadExtensions = rpcService.getProxy(MainContext.MainThreadExtensionService);
66
>
const mainThreadErrors = rpcService.getProxy(MainContext.MainThreadErrors);
67
>
68
>
const extensionsRegistry = await extensionService.getExtensionRegistry();
69
>
const extensionsMap = await extensionService.getExtensionPathIndex();
70
>
const extensionErrors = new WeakMap<Error, { extensionIdentifier: ExtensionIdentifier | undefined; stack: string }>();
71
>
72
>
// PART 1
73
>
// set the prepareStackTrace-handle and use it as a side-effect to associate errors
74
>
// with extensions - this works by looking up callsites in the extension path index
75
>
function prepareStackTraceAndFindExtension(error: Error, stackTrace: errors.V8CallSite[]) {
76
>
if (extensionErrors.has(error)) {
77
return extensionErrors.get(error)!.stack;
78
}
80
>
let extension: IExtensionDescription | undefined;
81
>
let fileName: string | null;
82
>
for (const call of stackTrace) {
83
>
stackTraceMessage += `\n\tat ${call.toString()}`;
84
>
fileName = call.getFileName();
85
>
if (!extension && fileName) {
86
>
extension = extensionsMap.findSubstr(URI.file(fileName));
87
>
}
88
>
}
89
>
const result = `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`;
90
>
extensionErrors.set(error, { extensionIdentifier: extension?.identifier, stack: result });
91
>
return result;
92
>
}
93
>
94
>
const _wasWrapped = Symbol('prepareStackTrace wrapped');
95
>
let _prepareStackTrace = prepareStackTraceAndFindExtension;
96
>
97
>
Object.defineProperty(Error, 'prepareStackTrace', {
98
>
configurable: false,
99
>
get() {
100
>
return _prepareStackTrace;
101
>
},
102
>
set(v) {
103
>
if (v === prepareStackTraceAndFindExtension || !v || v[_wasWrapped]) {
104
_prepareStackTrace = v || prepareStackTraceAndFindExtension;
105
return;
106
}
108
>
_prepareStackTrace = function (error, stackTrace) {
109
prepareStackTraceAndFindExtension(error, stackTrace);
110
return v.call(Error, error, stackTrace);
111
};
113
>
Object.assign(_prepareStackTrace, { [_wasWrapped]: true });
114
>
},
115
>
});
116
>
117
>
// PART 2
118
>
// set the unexpectedErrorHandler and check for extensions that have been identified as
119
>
// having caused the error. Note that the runtime order is actually reversed, the code
120
>
// below accesses the stack-property which triggers the code above
121
>
errors.setUnexpectedErrorHandler(err => {
122
123
if (!errors.PendingMigrationError.is(err)) {