working state for v8
MODIFY
packages/error-stack-shim/src/getStack.js
packages/error-stack-shim/src/getStack.js
@@ -15,7 +15,7 @@ const { getScrapedStackFramesUsing } = require('./scrapedStackFrames');
// accessor.
// If accessor provided, spec demands setter. But this is silly, so we
// we make it separately switchable.
-const PROVIDE_OPTIONAL_STACK_GETTER = false;
+const PROVIDE_OPTIONAL_STACK_GETTER = true;
const PROVIDE_OPTIONAL_STACK_SETTER = false;
const {
@@ -52,6 +52,29 @@ Error = FakeError;
}
});
+const stackGetter = PROVIDE_OPTIONAL_STACK_GETTER
+ ? function stackGetter() {
+ return getStackString(this);
+ }
+ : () => ' ';
+const stackSetter = PROVIDE_OPTIONAL_STACK_SETTER
+ ? function stackSetter(v) {
+ defineProperty(this, 'stack', {
+ value: v,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ });
+ }
+ : undefined;
+
+defineProperty(FakeError.prototype, 'stack', {
+ get: stackGetter,
+ set: stackSetter,
+ enumerable: false,
+ configurable: true,
+});
+
// Default if we can't do anything for a given platform
let getStackFrames = _error => harden([]);
@@ -88,15 +111,15 @@ function getStackFrameSpanString(span) {
function getFrameString(frame) {
const { name, source, span } = frame;
- let fullSource = source;
- if (typeof fullSource !== 'string') {
- fullSource = `eval ${getFrameString(fullSource)}`;
+ let location = source;
+ if (typeof location !== 'string') {
+ location = `eval ${getFrameString(location)}`;
}
const spanString = getStackFrameSpanString(span);
if (spanString) {
- fullSource = `${fullSource}:${spanString}`;
+ location = `${location}:${spanString}`;
}
- return `at ${name} (${fullSource})`;
+ return `at ${name} (${location})`;
}
function getStack(error) {
@@ -109,28 +132,5 @@ function getStackString(error) {
return getStack(error).string;
}
-const stackGetter = PROVIDE_OPTIONAL_STACK_GETTER
- ? function stackGetter() {
- return getStackString(this);
- }
- : () => ' ';
-const stackSetter = PROVIDE_OPTIONAL_STACK_SETTER
- ? function stackSetter(v) {
- defineProperty(this, 'stack', {
- value: v,
- writable: false,
- enumerable: false,
- configurable: true,
- });
- }
- : undefined;
-
-defineProperty(FakeError.prototype, 'stack', {
- get: stackGetter,
- set: stackSetter,
- enumerable: false,
- configurable: true,
-});
-
// export { getStack, getStackString };
module.exports = { getStack, getStackString };

MODIFY
packages/error-stack-shim/src/v8StackFrames.js
packages/error-stack-shim/src/v8StackFrames.js
// import { lineToFrame } from './scrapedStackFrames';
const { lineToFrame } = require('./scrapedStackFrames');
+const { defineProperty, getOwnPropertyDescriptor, apply } = Reflect;
+
function getV8StackFramesUsing(UnsafeError) {
const unsafeCaptureStackTrace = UnsafeError.captureStackTrace;
+ delete UnsafeError.captureStackTrace;
const ssts = new WeakMap(); // error -> sst
UnsafeError.prepareStackTrace = (error, sst) => {
ssts.set(error, sst);
- };
- UnsafeError.captureStackTrace = (obj, optMyError = undefined) => {
- const wasFrozen = Object.isFrozen(obj);
- const stackDesc = Object.getOwnPropertyDescriptor(obj, 'stack');
- try {
- const result = unsafeCaptureStackTrace(obj, optMyError);
- // eslint-disable-next-line no-unused-vars
- const ignore = obj.stack;
- return result;
- } finally {
- if (wasFrozen && !Object.isFrozen(obj)) {
- // TODO Do we still need to worry about this bug?
- // Was it ever filed? Issue url?
- if (stackDesc) {
- Object.defineProperty(obj, 'stack', stackDesc);
- } else {
- delete obj.stack;
- }
- Object.freeze(obj);
- }
- }
+ // See https://bugs.chromium.org/p/v8/issues/detail?id=9386
+ const desc = getOwnPropertyDescriptor(Error.prototype, 'stack');
+ return apply(desc.get, error, []);
};
function callSiteToFrame(callSite) {
@@ -45,9 +30,19 @@ function getV8StackFramesUsing(UnsafeError) {
const source = callSite.isEval()
? callSiteToFrame(callSite.getEvalOrigin())
: `${callSite.getFileName() || '?'}`;
- const name = `${callSite.getFunctionName() ||
+ let name = `${callSite.getFunctionName() ||
callSite.getMethodName() ||
'?'}`;
+ const typeName = callSite.getTypeName();
+ if (typeName) {
+ name = `${typeName}.${name}`;
+ }
+ if (callSite.isConstructor()) {
+ name = `new ${name}`;
+ }
+ if (typeof callSite.isAsync === 'function' && callSite.isAsync()) {
+ name = `async ${name}`;
+ }
return {
name,
source,

working state for v8