minor cleanups

This commit is contained in:
Vyacheslav Matyukhin 2022-10-05 15:49:16 +04:00
parent a45d6c6c57
commit 6463c4db5a
No known key found for this signature in database
GPG Key ID: 3D2A774C5489F96C
6 changed files with 15 additions and 17 deletions

View File

@ -22,7 +22,7 @@ const StackTrace: React.FC<Props> = ({ error }) => {
const frames = error.getFrameArray(); const frames = error.getFrameArray();
return frames.length ? ( return frames.length ? (
<div> <div>
<div>Traceback:</div> <div className="font-medium">Stack trace:</div>
<div className="ml-4"> <div className="ml-4">
{frames.map((frame, i) => ( {frames.map((frame, i) => (
<StackTraceFrame frame={frame} key={i} /> <StackTraceFrame frame={frame} key={i} />

View File

@ -36,6 +36,6 @@ export const run = (src, { output, sampleCount } = {}) => {
"Time:", "Time:",
String(time), String(time),
result.tag === "Error" ? red(result.tag) : green(result.tag), result.tag === "Error" ? red(result.tag) : green(result.tag),
result.tag === "Error" ? result.value.toStringWithStackTrace() : "" result.tag === "Error" ? result.value.toStringWithFrameStack() : ""
); );
}; };

View File

@ -1,3 +0,0 @@
// There are switch statement cases in the code which are impossible to reach by design.
// ImpossibleException is a sign of programming error.
exception ImpossibleException(string)

View File

@ -1,3 +1,6 @@
// This is called "frameStack" and not "callStack", because the last frame in errors is often not a function call.
// A "frame" is a pair of a scope (function or top-level scope, currently stored as a string) and a location inside it.
// See this comment to deconfuse about what a frame is: https://github.com/quantified-uncertainty/squiggle/pull/1172#issuecomment-1264115038
type t = Reducer_T.frameStack type t = Reducer_T.frameStack
module Frame = { module Frame = {
@ -18,9 +21,6 @@ module Frame = {
let make = (): t => list{} let make = (): t => list{}
@genType
let getTopFrame = (t: t): option<Reducer_T.frame> => Belt.List.head(t)
let extend = (t: t, name: string, location: option<Reducer_Peggy_Parse.location>) => let extend = (t: t, name: string, location: option<Reducer_Peggy_Parse.location>) =>
t->Belt.List.add({ t->Belt.List.add({
name: name, name: name,

View File

@ -82,7 +82,7 @@ let doLambdaCallFrom = (
inFunction: Some(t), inFunction: Some(t),
} }
SqError.rethrowWithStacktrace(() => { SqError.rethrowWithFrameStack(() => {
switch t { switch t {
| FnLambda({body}) => body(args, newContext, reducer) | FnLambda({body}) => body(args, newContext, reducer)
| FnBuiltin({body}) => body(args, newContext, reducer) | FnBuiltin({body}) => body(args, newContext, reducer)

View File

@ -1,7 +1,8 @@
type location = Reducer_Peggy_Parse.location type location = Reducer_Peggy_Parse.location
// Messages don't contain any stack trace information. // Messages don't contain any stack trace information.
// FunctionRegistry functions are allowed to throw MessageExceptions, though, because they will be caught and rewrapped by Reducer_Lambda code // FunctionRegistry functions are allowed to throw MessageExceptions, though,
// because they will be caught and rewrapped by Reducer_Lambda code.
module Message = { module Message = {
@genType.opaque @genType.opaque
type t = type t =
@ -125,16 +126,16 @@ let getFrameArray = (t: t): array<Reducer_T.frame> => t.frameStack->Reducer_Fram
@genType @genType
let toStringWithStackTrace = (t: t) => let toStringWithStackTrace = (t: t) =>
t->toString ++ if t.frameStack->Reducer_FrameStack.isEmpty { t->toString ++ if t.frameStack->Reducer_FrameStack.isEmpty {
"\nTraceback:\n" ++ t.frameStack->Reducer_FrameStack.toString "\nStack trace:\n" ++ t.frameStack->Reducer_FrameStack.toString
} else { } else {
"" ""
} }
let throw = (t: t) => t->SqException->raise let throw = (t: t) => t->SqException->raise
let throwMessageWithFrameStack = (message: Message.t, frameStack: Reducer_FrameStack.t) => let throwMessageWithFrameStack = (message: Message.t, frameStack: Reducer_FrameStack.t) =>
fromMessageWithFrameStack(message, frameStack)->throw message->fromMessageWithFrameStack(frameStack)->throw
// this shouldn't be used for most runtime errors - the resulting error would have an empty stacktrace // this shouldn't be used for most runtime errors - the resulting error would have an empty framestack
let fromException = exn => let fromException = exn =>
switch exn { switch exn {
| SqException(e) => e | SqException(e) => e
@ -143,14 +144,14 @@ let fromException = exn =>
| _ => REOther("Unknown exception")->fromMessage | _ => REOther("Unknown exception")->fromMessage
} }
// converts raw exceptions into exceptions with stacktrace attached // converts raw exceptions into exceptions with framestack attached
// already converted exceptions won't be affected // already converted exceptions won't be affected
let rethrowWithStacktrace = (fn: unit => 'a, frameStack: Reducer_FrameStack.t) => { let rethrowWithFrameStack = (fn: unit => 'a, frameStack: Reducer_FrameStack.t) => {
try { try {
fn() fn()
} catch { } catch {
| SqException(e) => e->throw // exception already has a stacktrace | SqException(e) => e->throw // exception already has a framestack
| Message.MessageException(e) => e->throwMessageWithFrameStack(frameStack) // probably comes from FunctionRegistry, adding stacktrace | Message.MessageException(e) => e->throwMessageWithFrameStack(frameStack) // probably comes from FunctionRegistry, adding framestack
| Js.Exn.Error(obj) => | Js.Exn.Error(obj) =>
REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->throwMessageWithFrameStack(frameStack) REJavaScriptExn(obj->Js.Exn.message, obj->Js.Exn.name)->throwMessageWithFrameStack(frameStack)
| _ => REOther("Unknown exception")->throwMessageWithFrameStack(frameStack) | _ => REOther("Unknown exception")->throwMessageWithFrameStack(frameStack)