diff --git a/packages/components/src/components/SquiggleErrorAlert.tsx b/packages/components/src/components/SquiggleErrorAlert.tsx
index fb4721eb..c4b14f17 100644
--- a/packages/components/src/components/SquiggleErrorAlert.tsx
+++ b/packages/components/src/components/SquiggleErrorAlert.tsx
@@ -1,4 +1,4 @@
-import { SqError, SqLocation } from "@quri/squiggle-lang";
+import { SqError, SqFrame } from "@quri/squiggle-lang";
import React from "react";
import { ErrorAlert } from "./Alert";
@@ -6,24 +6,26 @@ type Props = {
error: SqError;
};
-const StackTraceLocation: React.FC<{ location: SqLocation }> = ({
- location,
-}) => {
+const StackTraceFrame: React.FC<{ frame: SqFrame }> = ({ frame }) => {
+ const location = frame.location();
return (
- Line {location.start.line}, column {location.start.column}
+ {frame.name()}
+ {location
+ ? ` at line ${location.start.line}, column ${location.start.column}`
+ : ""}
);
};
const StackTrace: React.FC = ({ error }) => {
- const locations = error.toLocationArray();
- return locations.length ? (
+ const frames = error.getFrameArray();
+ return frames.length ? (
Traceback:
- {locations.map((location, i) => (
-
+ {frames.map((frame, i) => (
+
))}
diff --git a/packages/components/src/lib/utility.ts b/packages/components/src/lib/utility.ts
index c3ce08a4..cb002954 100644
--- a/packages/components/src/lib/utility.ts
+++ b/packages/components/src/lib/utility.ts
@@ -45,7 +45,7 @@ export function getValueToRender({ result, bindings }: ResultAndBindings) {
export function getErrorLocations(result: ResultAndBindings["result"]) {
if (result.tag === "Error") {
- const location = result.value.toLocation();
+ const location = result.value.location();
return location ? [location] : [];
} else {
return [];
diff --git a/packages/squiggle-lang/src/js/SqError.ts b/packages/squiggle-lang/src/js/SqError.ts
index 61d09096..59036830 100644
--- a/packages/squiggle-lang/src/js/SqError.ts
+++ b/packages/squiggle-lang/src/js/SqError.ts
@@ -1,8 +1,9 @@
import * as RSError from "../rescript/SqError.gen";
+import * as RSReducerT from "../rescript/Reducer/Reducer_T.gen";
-import * as RSCallStack from "../rescript/Reducer/Reducer_CallStack.gen";
+import * as RSFrameStack from "../rescript/Reducer/Reducer_FrameStack.gen";
-export type SqFrame = RSCallStack.frame;
+export { location as SqLocation } from "../rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.gen";
export class SqError {
constructor(private _value: RSError.t) {}
@@ -19,17 +20,31 @@ export class SqError {
return new SqError(RSError.createOtherError(v));
}
- getTopFrame(): SqCallFrame | undefined {
- const frame = RSCallStack.getTopFrame(RSError.getStackTrace(this._value));
- return frame ? new SqCallFrame(frame) : undefined;
+ getTopFrame(): SqFrame | undefined {
+ const frame = RSFrameStack.getTopFrame(RSError.getFrameStack(this._value));
+ return frame ? new SqFrame(frame) : undefined;
}
- getFrameArray(): SqCallFrame[] {
+ getFrameArray(): SqFrame[] {
const frames = RSError.getFrameArray(this._value);
- return frames.map((frame) => new SqCallFrame(frame));
+ return frames.map((frame) => new SqFrame(frame));
+ }
+
+ location() {
+ return this.getTopFrame()?.location();
}
}
-export class SqCallFrame {
- constructor(private _value: SqFrame) {}
+export class SqFrame {
+ constructor(private _value: RSReducerT.frame) {}
+
+ name(): string {
+ return RSFrameStack.Frame.toName(this._value);
+ }
+
+ location() {
+ console.log(RSFrameStack);
+ console.log(RSFrameStack.Frame);
+ return RSFrameStack.Frame.toLocation(this._value);
+ }
}
diff --git a/packages/squiggle-lang/src/js/SqValueLocation.ts b/packages/squiggle-lang/src/js/SqValueLocation.ts
index 33c7060b..ad2e7e02 100644
--- a/packages/squiggle-lang/src/js/SqValueLocation.ts
+++ b/packages/squiggle-lang/src/js/SqValueLocation.ts
@@ -1,4 +1,3 @@
-import { isParenthesisNode } from "mathjs";
import { SqProject } from "./SqProject";
type PathItem = string | number;
diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts
index aac26bd5..886c830a 100644
--- a/packages/squiggle-lang/src/js/index.ts
+++ b/packages/squiggle-lang/src/js/index.ts
@@ -13,7 +13,7 @@ export {
environment,
defaultEnvironment,
} from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution.gen";
-export { SqError } from "./SqError";
+export { SqError, SqFrame, SqLocation } from "./SqError";
export { SqShape } from "./SqPointSetDist";
export { resultMap } from "./types";
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res
index af596dc2..a2d98f92 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res
@@ -4,8 +4,13 @@ let defaultEnvironment: Reducer_T.environment = DistributionOperation.defaultEnv
let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environment): t => {
{
- callStack: list{},
+ frameStack: list{},
bindings: stdLib->Reducer_Bindings.fromNamespace->Reducer_Bindings.extend,
environment: environment,
+ inFunction: None,
}
}
+
+let currentFunctionName = (t: t): string => {
+ t.inFunction->E.O2.fmap(Reducer_Lambda_T.name)->E.O2.default("")
+}
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res
index f334335a..0036816b 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res
@@ -2,14 +2,16 @@ module Bindings = Reducer_Bindings
module Result = Belt.Result
module T = Reducer_T
-let toLocation = (expression: T.expression): SqError.location => {
+let toLocation = (expression: T.expression): Reducer_Peggy_Parse.location => {
expression.ast.location
}
let throwFrom = (error: SqError.Message.t, expression: T.expression, context: T.context) =>
- error->SqError.throwMessage(
- context.callStack,
- location: Some(expression->toLocation)
+ error->SqError.throwMessageWithFrameStack(
+ context.frameStack->Reducer_FrameStack.extend(
+ context->Reducer_Context.currentFunctionName,
+ Some(expression->toLocation),
+ ),
)
/*
@@ -93,9 +95,9 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => {
}
}
- | T.ELambda(parameters, body) => (
+ | T.ELambda(parameters, body, name) => (
Reducer_Lambda.makeLambda(
- None, // TODO - pass function name from parser
+ name,
parameters,
context.bindings,
body,
@@ -112,7 +114,13 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => {
})
switch lambda {
| T.IEvLambda(lambda) => {
- let result = Reducer_Lambda.doLambdaCall(lambda, argValues, context, evaluate)
+ let result = Reducer_Lambda.doLambdaCallFrom(
+ lambda,
+ argValues,
+ context,
+ evaluate,
+ Some(expression->toLocation), // we have to pass the location of a current expression here, to put it on frameStack
+ )
(result, context)
}
| _ => RENotAFunction(lambda->Reducer_Value.toString)->throwFrom(expression, context)
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res
index 965fc499..527331fb 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res
@@ -9,10 +9,11 @@ let eBool = aBool => aBool->T.IEvBool->T.EValue
let eCall = (fn: expression, args: array): expressionContent => T.ECall(fn, args)
-let eLambda = (parameters: array, expr: expression): expressionContent => T.ELambda(
- parameters,
- expr,
-)
+let eLambda = (
+ parameters: array,
+ expr: expression,
+ name: option,
+): expressionContent => T.ELambda(parameters, expr, name)
let eNumber = aNumber => aNumber->T.IEvNumber->T.EValue
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res
index 6b2982f6..c7804c7a 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res
@@ -24,7 +24,7 @@ let rec toString = (expression: t) =>
`${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})`
| EAssign(name, value) => `${name} = ${value->toString}`
| ECall(fn, args) => `(${fn->toString})(${args->Js.Array2.map(toString)->commaJoin})`
- | ELambda(parameters, body) => `{|${parameters->commaJoin}| ${body->toString}}`
+ | ELambda(parameters, body, _) => `{|${parameters->commaJoin}| ${body->toString}}`
| EValue(aValue) => Reducer_Value.toString(aValue)
}
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_FrameStack.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_FrameStack.res
index 217993f0..e61efd5d 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_FrameStack.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_FrameStack.res
@@ -1,37 +1,43 @@
type t = Reducer_T.frameStack
module Frame = {
- let toString = ({lambda, location}: Reducer_T.frame) =>
- `${fromFrame} at ${location.start.line->Js.Int.toString}, column ${location.start.column->Js.Int.toString}`
+ let toString = ({name, location}: Reducer_T.frame) =>
+ name ++
+ switch location {
+ | Some(location) =>
+ ` at line ${location.start.line->Js.Int.toString}, column ${location.start.column->Js.Int.toString}`
+ | None => ""
+ }
+
+ @genType
+ let toLocation = (t: Reducer_T.frame): option => t.location
+
+ @genType
+ let toName = (t: Reducer_T.frame): string => t.name
}
let make = (): t => list{}
-let topFrameName = (t: t) =>
- switch t->getTopFrame {
- | Some({lambda}) =>
- switch lambda {
- | FnLambda({name}) => name
- | FnBuiltin({name}) => name
- }
- | None => ""
- }
+@genType
+let getTopFrame = (t: t): option => Belt.List.head(t)
-let extend = (t: t, lambda: Reducer_T.lambdaValue, location: option) =>
+let extend = (t: t, name: string, location: option) =>
t->Belt.List.add({
- lambda: lambda,
- fromLocation: location,
- fromFrame: t->topFrameName,
+ name: name,
+ location: location,
})
let toString = (t: t) =>
- t->Belt.List.map(s => " " ++ s->toStringFrame ++ "\n")->Belt.List.toArray->Js.Array2.joinWith("")
+ t
+ ->Belt.List.map(s => " " ++ s->Frame.toString ++ "\n")
+ ->Belt.List.toArray
+ ->Js.Array2.joinWith("")
@genType
-let toFrameArray = (t: t): array => t->Belt.List.toArray
+let toFrameArray = (t: t): array => t->Belt.List.toArray
@genType
-let getTopFrame = (t: t): option => t->Belt.List.head
+let getTopFrame = (t: t): option => t->Belt.List.head
let isEmpty = (t: t): bool =>
switch t->Belt.List.head {
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda.res
index 04adeea0..98a272db 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda.res
@@ -33,7 +33,8 @@ let makeLambda = (
let lambdaContext: Reducer_T.context = {
bindings: localBindingsWithParameters, // based on bindings at the moment of lambda creation
environment: context.environment, // environment at the moment when lambda is called
- callStack: context.callStack, // extended by main `evaluate` function
+ frameStack: context.frameStack, // already extended in `doLambdaCall`
+ inFunction: context.inFunction, // already updated in `doLambdaCall`
}
let (value, _) = reducer(body, lambdaContext)
@@ -49,7 +50,7 @@ let makeLambda = (
})
}
-// stdlib lambdas (everything in FunctionRegistry) is built by this method. Body is generated in SquiggleLibrary_StdLib.res
+// stdlib functions (everything in FunctionRegistry) are built by this method. Body is generated in SquiggleLibrary_StdLib.res
let makeFFILambda = (name: string, body: Reducer_T.lambdaBody): t => FnBuiltin({
// Note: current bindings could be accidentally exposed here through context (compare with native lambda implementation above, where we override them with local bindings).
// But FunctionRegistry API is too limited for that to matter. Please take care not to violate that in the future by accident.
@@ -65,10 +66,20 @@ let parameters = (t: t): array => {
}
}
-let doLambdaCall = (t: t, args, context: Reducer_Context.t, reducer) => {
+let doLambdaCallFrom = (
+ t: t,
+ args: array,
+ context: Reducer_T.context,
+ reducer,
+ location: option,
+) => {
let newContext = {
...context,
- callStack: t->Reducer_CallStack.extend(t),
+ frameStack: context.frameStack->Reducer_FrameStack.extend(
+ context->Reducer_Context.currentFunctionName,
+ location,
+ ),
+ inFunction: Some(t),
}
SqError.rethrowWithStacktrace(() => {
@@ -76,5 +87,9 @@ let doLambdaCall = (t: t, args, context: Reducer_Context.t, reducer) => {
| FnLambda({body}) => body(args, newContext, reducer)
| FnBuiltin({body}) => body(args, newContext, reducer)
}
- }, newContext.callStack)
+ }, newContext.frameStack)
+}
+
+let doLambdaCall = (t: t, args, context, reducer) => {
+ doLambdaCallFrom(t, args, context, reducer, None)
}
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda_T.res
new file mode 100644
index 00000000..ab0724b4
--- /dev/null
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Lambda_T.res
@@ -0,0 +1,8 @@
+type t = Reducer_T.lambdaValue
+
+let name = (t: t): string => {
+ switch t {
+ | FnLambda({name}) => name->E.O2.default("")
+ | FnBuiltin({name}) => name
+ }
+}
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy
index 0cd28a86..cbe1f9da 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy
@@ -50,7 +50,7 @@ letStatement
defunStatement
= variable:variable '(' _nl args:array_parameters _nl ')' _ assignmentOp _nl body:innerBlockOrExpression
- { var value = h.nodeLambda(args, body, location())
+ { var value = h.nodeLambda(args, body, location(), variable)
return h.nodeLetStatement(variable, value, location()) }
assignmentOp "assignment" = '='
@@ -261,9 +261,9 @@ valueConstructor
lambda
= '{' _nl '|' _nl args:array_parameters _nl '|' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}'
{ statements.push(finalExpression)
- return h.nodeLambda(args, h.nodeBlock(statements, location()), location()) }
+ return h.nodeLambda(args, h.nodeBlock(statements, location()), location(), undefined) }
/ '{' _nl '|' _nl args:array_parameters _nl '|' _nl finalExpression: expression _nl '}'
- { return h.nodeLambda(args, finalExpression, location()) }
+ { return h.nodeLambda(args, finalExpression, location(), undefined) }
arrayConstructor 'array'
= '[' _nl ']'
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res
index b2b57bed..001f3e5b 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res
@@ -44,7 +44,7 @@ type nodeIdentifier = {...node, "value": string}
type nodeInteger = {...node, "value": int}
type nodeKeyValue = {...node, "key": node, "value": node}
type nodeRecord = {...node, "elements": array}
-type nodeLambda = {...node, "args": array, "body": node}
+type nodeLambda = {...node, "args": array, "body": node, "name": option}
type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node}
type nodeModuleIdentifier = {...node, "value": string}
type nodeString = {...node, "value": string}
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res
index 6c187476..2e858c55 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res
@@ -20,7 +20,7 @@ let rec fromNode = (node: Parse.node): expression => {
nodeLambda["args"]->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"])
let body = nodeLambda["body"]->fromNode
- ExpressionBuilder.eLambda(args, body)
+ ExpressionBuilder.eLambda(args, body, nodeLambda["name"])
}
let caseRecord = (nodeRecord): expressionContent => {
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts
index 6e9fe80c..6253b875 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts
@@ -89,6 +89,7 @@ type NodeLambda = Node & {
type: "Lambda";
args: AnyPeggyNode[];
body: AnyPeggyNode;
+ name?: string;
};
type NodeTernary = Node & {
@@ -217,9 +218,10 @@ export function nodeKeyValue(
export function nodeLambda(
args: AnyPeggyNode[],
body: AnyPeggyNode,
- location: LocationRange
+ location: LocationRange,
+ name?: NodeIdentifier
): NodeLambda {
- return { type: "Lambda", args, body, location };
+ return { type: "Lambda", args, body, location, name: name?.value };
}
export function nodeLetStatement(
variable: NodeIdentifier,
diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res
index eab7bd55..dcc9e4bf 100644
--- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res
+++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res
@@ -36,7 +36,7 @@ and expressionContent =
| ETernary(expression, expression, expression)
| EAssign(string, expression)
| ECall(expression, array)
- | ELambda(array, expression)
+ | ELambda(array, expression, option)
| EValue(value)
and expression = {
@@ -50,18 +50,18 @@ and bindings = {
parent: option,
}
+@genType.opaque
and frame = {
name: string,
location: option, // can be empty for calls from builtin functions
}
-
-and frameStack = list
+@genType.opaque and frameStack = list
and context = {
bindings: bindings,
environment: environment,
- inFunction: option, // used to build the next frame in frameStack
- callStack: frameStack,
+ frameStack: frameStack,
+ inFunction: option,
}
and reducerFn = (expression, context) => (value, context)
diff --git a/packages/squiggle-lang/src/rescript/SqError.res b/packages/squiggle-lang/src/rescript/SqError.res
index 461e1feb..29d98517 100644
--- a/packages/squiggle-lang/src/rescript/SqError.res
+++ b/packages/squiggle-lang/src/rescript/SqError.res
@@ -95,19 +95,19 @@ type t = {
exception SqException(t)
-// `context` should be specified for runtime errors, but can be left empty for errors from Reducer_Project and so on.
-// `location` can be empty for errors raised from FunctionRegistry.
-let fromMessage = (message: Message.t, frameStack: Reducer_FrameStack.t): t => {
+let fromMessageWithFrameStack = (message: Message.t, frameStack: Reducer_FrameStack.t): t => {
message: message,
- stackTrace: stackTrace,
+ frameStack: frameStack,
}
-let fromMessageWithoutFrameStack = (message: Message.t) =>
- fromMessage(message, Reducer_FrameStack.make())
+// this shouldn't be used much, since frame stack will be empty
+// but it's useful for global errors, e.g. in ReducerProject or somethere in the frontend
+@genType
+let fromMessage = (message: Message.t) =>
+ fromMessageWithFrameStack(message, Reducer_FrameStack.make())
@genType
-let getTopFrame = (t: t): option =>
- t.stackTrace->Reducer_FrameStack.getTopFrame
+let getTopFrame = (t: t): option => t.frameStack->Reducer_FrameStack.getTopFrame
@genType
let getFrameStack = (t: t): Reducer_FrameStack.t => t.frameStack
@@ -116,42 +116,42 @@ let getFrameStack = (t: t): Reducer_FrameStack.t => t.frameStack
let toString = (t: t): string => t.message->Message.toString
@genType
-let createOtherError = (v: string): t => Message.REOther(v)->fromMessageWithoutFrameStack
+let createOtherError = (v: string): t => Message.REOther(v)->fromMessage
@genType
-let getFrameArray = (t: t): array =>
- t.stackTrace->Reducer_CallStack.toFrameArray
+let getFrameArray = (t: t): array => t.frameStack->Reducer_FrameStack.toFrameArray
@genType
-let toStringWithStacktrace = (t: t) =>
+let toStringWithStackTrace = (t: t) =>
t->toString ++ if t.frameStack->Reducer_FrameStack.isEmpty {
- "Traceback:\n" ++ t.frameStack->Reducer_FrameStack.toString
+ "\nTraceback:\n" ++ t.frameStack->Reducer_FrameStack.toString
+ } else {
+ ""
}
let throw = (t: t) => t->SqException->raise
-let throwMessage = (message: Message.t, frameStack: Reducer_FrameStack.t) =>
- fromMessage(message, frameStack)->throw
+let throwMessageWithFrameStack = (message: Message.t, frameStack: Reducer_FrameStack.t) =>
+ fromMessageWithFrameStack(message, frameStack)->throw
// this shouldn't be used for most runtime errors - the resulting error would have an empty stacktrace
let fromException = exn =>
switch exn {
| SqException(e) => e
- | Message.MessageException(e) => e->fromMessage(Reducer_CallStack.make())
- | Js.Exn.Error(obj) =>
- REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->fromMessageWithoutStacktrace
- | _ => REOther("Unknown exception")->fromMessageWithoutStacktrace
+ | Message.MessageException(e) => e->fromMessage
+ | Js.Exn.Error(obj) => REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->fromMessage
+ | _ => REOther("Unknown exception")->fromMessage
}
// converts raw exceptions into exceptions with stacktrace attached
// already converted exceptions won't be affected
-let rethrowWithStacktrace = (fn: unit => 'a, stackTrace: Reducer_CallStack.t) => {
+let rethrowWithStacktrace = (fn: unit => 'a, frameStack: Reducer_FrameStack.t) => {
try {
fn()
} catch {
| SqException(e) => e->throw // exception already has a stacktrace
- | Message.MessageException(e) => e->throwMessage(stackTrace) // probably comes from FunctionRegistry, adding stacktrace
+ | Message.MessageException(e) => e->throwMessageWithFrameStack(frameStack) // probably comes from FunctionRegistry, adding stacktrace
| Js.Exn.Error(obj) =>
- REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->throwMessage(stackTrace)
- | _ => REOther("Unknown exception")->throwMessage(stackTrace)
+ REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->throwMessageWithFrameStack(frameStack)
+ | _ => REOther("Unknown exception")->throwMessageWithFrameStack(frameStack)
}
}