Add message to error stack (#2311)

Summary:
Because of an ordering bug messages weren’t being added to the error stacks thrown by Prepack. This made debugging runtime issues in generated Prepack code difficult.

```js
throw new Error("foo");
```

```js
(function() {
  var $$0 = {
    enumerable: false,
    configurable: true,
    writable: true,
  };

  var _$0 = this;

  var _$1 = _$0.Error;
  var _$2 = _$1.prototype;
  var _$3 = _$0.Object;
  var _$4 = _$3.defineProperty;

  var __constructor = function() {};

  var _0 = ((__constructor.prototype = _$2), new __constructor());

  ($$0.value = "Error\n    at /Users/calebmer/prepack/fb-www/input.js:4:7"), _$4(_0, "stack", $$0);
  ($$0.value = "foo"), _$4(_0, "message", $$0);
  throw _0;
}.call(this));
```

```js
(function() {
  var $$0 = {
    enumerable: false,
    configurable: true,
    writable: true,
  };

  var _$0 = this;

  var _$1 = _$0.Error;
  var _$2 = _$1.prototype;
  var _$3 = _$0.Object;
  var _$4 = _$3.defineProperty;

  var __constructor = function() {};

  var _0 = ((__constructor.prototype = _$2), new __constructor());

  ($$0.value = "foo"), _$4(_0, "message", $$0);
  ($$0.value = "Error: foo\n    at /Users/calebmer/prepack/fb-www/input.js:4:7"), _$4(_0, "stack", $$0);
  throw _0;
}.call(this));
```
Pull Request resolved: https://github.com/facebook/prepack/pull/2311

Differential Revision: D9005517

Pulled By: calebmer

fbshipit-source-id: 8567624a67a78085d4072560541785e412cd6645
This commit is contained in:
Caleb Meredith 2018-07-25 16:13:03 -07:00 committed by Facebook Github Bot
parent 3bcd3fb4ee
commit 93b8e764b5

View File

@ -11,10 +11,18 @@
import type { Realm } from "../../realm.js";
import type { LexicalEnvironment } from "../../environment.js";
import { ObjectValue, FunctionValue, NativeFunctionValue, StringValue } from "../../values/index.js";
import {
AbstractValue,
ObjectValue,
FunctionValue,
NativeFunctionValue,
StringValue,
Value,
} from "../../values/index.js";
import { Get } from "../../methods/index.js";
import { Create, Properties, To } from "../../singletons.js";
import invariant from "../../invariant.js";
import buildExpressionTemplate from "../../utils/builder.js";
import type { BabelNodeSourceLocation } from "@babel/types";
export default function(realm: Realm): NativeFunctionValue {
@ -76,23 +84,23 @@ export function describeLocation(
return location;
}
function buildStack(realm: Realm, context: ObjectValue) {
const buildStackTemplateSrc = 'A + (B ? ": " + B : "") + C';
const buildStackTemplate = buildExpressionTemplate(buildStackTemplateSrc);
function buildStack(realm: Realm, context: ObjectValue): Value {
invariant(context.$ErrorData);
let stack = context.$ErrorData.contextStack;
if (!stack) return realm.intrinsics.undefined;
let lines = [];
let header = "";
let header = To.ToStringPartial(realm, Get(realm, context, "name"));
header += To.ToStringPartial(realm, Get(realm, context, "name"));
let msg = Get(realm, context, "message");
if (!msg.mightBeUndefined()) {
msg = To.ToStringPartial(realm, msg);
if (msg) header += `: ${msg}`;
let message = Get(realm, context, "message");
if (!message.mightBeUndefined()) {
message = To.ToStringValue(realm, message);
} else {
msg.throwIfNotConcrete();
message.throwIfNotConcrete();
}
for (let executionContext of stack.reverse()) {
@ -106,8 +114,17 @@ function buildStack(realm: Realm, context: ObjectValue) {
);
if (locString !== undefined) lines.push(locString);
}
let footer = `\n ${lines.join("\n ")}`;
return new StringValue(realm, `${header}\n ${lines.join("\n ")}`);
return message instanceof StringValue
? new StringValue(realm, `${header}${message.value ? `: ${message.value}` : ""}${footer}`)
: AbstractValue.createFromTemplate(
realm,
buildStackTemplate,
StringValue,
[new StringValue(realm, header), message, new StringValue(realm, footer)],
buildStackTemplateSrc
);
}
export function build(name: string, realm: Realm, inheritError?: boolean = true): NativeFunctionValue {
@ -122,15 +139,6 @@ export function build(name: string, realm: Realm, inheritError?: boolean = true)
locationData: undefined,
};
// Build a text description of the stack.
let stackDesc = {
value: buildStack(realm, O),
enumerable: false,
configurable: true,
writable: true,
};
Properties.DefinePropertyOrThrow(realm, O, "stack", stackDesc);
// 3. If message is not undefined, then
if (!message.mightBeUndefined()) {
// a. Let msg be ? ToString(message).
@ -150,6 +158,15 @@ export function build(name: string, realm: Realm, inheritError?: boolean = true)
message.throwIfNotConcrete();
}
// Build a text description of the stack.
let stackDesc = {
value: buildStack(realm, O),
enumerable: false,
configurable: true,
writable: true,
};
Properties.DefinePropertyOrThrow(realm, O, "stack", stackDesc);
// 4. Return O.
return O;
});