Skip to content

Commit 3630c30

Browse files
committed
fix(ses): fix #2951 stronger sniffing for v8
1 parent 5885418 commit 3630c30

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

packages/ses/src/error/tame-error-constructor.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getOwnPropertyDescriptor,
88
defineProperty,
99
getOwnPropertyDescriptors,
10+
isArray,
1011
} from '../commons.js';
1112
import { NativeErrors } from '../permits.js';
1213
import { tameV8ErrorConstructor } from './tame-v8-error-constructor.js';
@@ -37,9 +38,44 @@ export default function tameErrorConstructor(
3738
) {
3839
const ErrorPrototype = FERAL_ERROR.prototype;
3940

40-
const { captureStackTrace: originalCaptureStackTrace } = FERAL_ERROR;
41-
const platform =
42-
typeof originalCaptureStackTrace === 'function' ? 'v8' : 'unknown';
41+
const {
42+
captureStackTrace: originalCaptureStackTrace,
43+
prepareStackTrace: originalPrepareStackTrace,
44+
} = FERAL_ERROR;
45+
let platform = 'unknown';
46+
if (typeof originalCaptureStackTrace === 'function') {
47+
// we might be on v8
48+
if (typeof originalPrepareStackTrace === 'function') {
49+
// This case should not occur on v8 or any other platform.
50+
// But if it does, we assume we're on v8, or a platform whose
51+
// error stack logic is close enough that we can treat it
52+
// like v8.
53+
platform = 'v8';
54+
} else {
55+
try {
56+
FERAL_ERROR.prepareStackTrace = (error, sst) => {
57+
// eslint-disable-next-line no-use-before-define
58+
if (error === sacrificialError && isArray(sst)) {
59+
// v8 implements `prepareStackTrace`. But on v8 the initial state
60+
// of the original error constructor, `FERAL_ERROR`, has no
61+
// `prepareStackTrace` property. To test whether the current
62+
// platform implements it,
63+
// we must set our own and then see if `error.stack` triggers it.
64+
// If so, then we assume we're on v8, or a platform whose
65+
// error stack logic is close enough that we can treat it
66+
// like v8.
67+
platform = 'v8';
68+
}
69+
};
70+
const sacrificialError = new FERAL_ERROR('just for testing');
71+
// Intentionally accesses `sacrificialError.stack` only to trigger
72+
// the test `prepareStackTrace` for platform detection.
73+
sacrificialError.stack;
74+
} finally {
75+
delete FERAL_ERROR.prepareStackTrace;
76+
}
77+
}
78+
}
4379

4480
const makeErrorConstructor = (_ = {}) => {
4581
// eslint-disable-next-line no-shadow

0 commit comments

Comments
 (0)