Skip to content

Commit c7d9530

Browse files
committed
use equality check instead of Symbol, cache results and prevent double computation when "recursive" calls happen
1 parent 61eccf4 commit c7d9530

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

src/vs/workbench/api/common/extensionHostMain.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,15 @@ abstract class ErrorHandler {
6565
const mainThreadErrors = rpcService.getProxy(MainContext.MainThreadErrors);
6666

6767
const map = await extensionService.getExtensionPathIndex();
68-
const extensionErrors = new WeakMap<Error, ExtensionIdentifier | undefined>();
68+
const extensionErrors = new WeakMap<Error, { extensionIdentifier: ExtensionIdentifier | undefined; stack: string }>();
6969

7070
// PART 1
7171
// set the prepareStackTrace-handle and use it as a side-effect to associate errors
7272
// with extensions - this works by looking up callsites in the extension path index
7373
function prepareStackTraceAndFindExtension(error: Error, stackTrace: errors.V8CallSite[]) {
74+
if (extensionErrors.has(error)) {
75+
return extensionErrors.get(error)!.stack;
76+
}
7477
let stackTraceMessage = '';
7578
let extension: IExtensionDescription | undefined;
7679
let fileName: string | null;
@@ -81,20 +84,21 @@ abstract class ErrorHandler {
8184
extension = map.findSubstr(URI.file(fileName));
8285
}
8386
}
84-
extensionErrors.set(error, extension?.identifier);
85-
return `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`;
87+
const result = `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`;
88+
extensionErrors.set(error, { extensionIdentifier: extension?.identifier, stack: result });
89+
return result;
8690
}
8791

88-
const _wasWrapped = Symbol('prepareStackTrace wrapped');
8992
let _prepareStackTrace = prepareStackTraceAndFindExtension;
90-
Object.assign(_prepareStackTrace, { [_wasWrapped]: true });
93+
9194
Object.defineProperty(Error, 'prepareStackTrace', {
9295
configurable: false,
9396
get() {
9497
return _prepareStackTrace;
9598
},
9699
set(v) {
97-
if (v && (v as any)[_wasWrapped]) {
100+
if (v === prepareStackTraceAndFindExtension) {
101+
// back to default
98102
_prepareStackTrace = v;
99103
return;
100104
}
@@ -103,8 +107,6 @@ abstract class ErrorHandler {
103107
prepareStackTraceAndFindExtension(error, stackTrace);
104108
return v.call(Error, error, stackTrace);
105109
};
106-
107-
Object.assign(_prepareStackTrace, { [_wasWrapped]: true });
108110
},
109111
});
110112

@@ -115,16 +117,16 @@ abstract class ErrorHandler {
115117
errors.setUnexpectedErrorHandler(err => {
116118
logService.error(err);
117119

118-
const data = errors.transformErrorForSerialization(err);
119-
const extension = extensionErrors.get(err);
120-
if (!extension) {
121-
mainThreadErrors.$onUnexpectedError(data);
120+
const errorData = errors.transformErrorForSerialization(err);
121+
const stackData = extensionErrors.get(err);
122+
if (!stackData?.extensionIdentifier) {
123+
mainThreadErrors.$onUnexpectedError(errorData);
122124
return;
123125
}
124126

125-
mainThreadExtensions.$onExtensionRuntimeError(extension, data);
126-
const reported = extensionTelemetry.onExtensionError(extension, err);
127-
logService.trace('forwarded error to extension?', reported, extension);
127+
mainThreadExtensions.$onExtensionRuntimeError(stackData.extensionIdentifier, errorData);
128+
const reported = extensionTelemetry.onExtensionError(stackData.extensionIdentifier, err);
129+
logService.trace('forwarded error to extension?', reported, stackData);
128130
});
129131
}
130132
}

0 commit comments

Comments
 (0)