From 3e778deba0f165a884d0f0d79ca17b6ccb7190cf Mon Sep 17 00:00:00 2001 From: Fons van der Plas Date: Thu, 15 Feb 2024 16:59:56 +0100 Subject: [PATCH] Stacktraces: shorter for macro expansion and `@Kwargs` in Julia 1.10 (#2812) --- frontend/components/CellInput.js | 1 - frontend/components/ErrorMessage.js | 46 +++++++++++------------ src/runner/PlutoRunner/src/PlutoRunner.jl | 37 +++++++++++++----- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/frontend/components/CellInput.js b/frontend/components/CellInput.js index 1b9b108222..f1230f93ff 100644 --- a/frontend/components/CellInput.js +++ b/frontend/components/CellInput.js @@ -936,7 +936,6 @@ const InputContextMenu = ({ on_delete, cell_id, run_cell, skip_as_script, runnin const prevously_focused_element_ref = useRef(/** @type {Element?} */ (null)) const setOpen = (val) => { - console.error("setOpen", val) if (val) { prevously_focused_element_ref.current = document.activeElement } diff --git a/frontend/components/ErrorMessage.js b/frontend/components/ErrorMessage.js index 60e83a1515..f5f43ea58a 100644 --- a/frontend/components/ErrorMessage.js +++ b/frontend/components/ErrorMessage.js @@ -9,6 +9,7 @@ const StackFrameFilename = ({ frame, cell_id }) => { if (sep_index != -1) { const frame_cell_id = frame.file.substr(sep_index + 4, 36) const a = html` { window.dispatchEvent( @@ -58,24 +59,24 @@ export const ParseError = ({ cell_id, diagnostics }) => {

Syntax error

-
    - ${diagnostics.map( - ({ message, from, to, line }) => - html`
  1. // NOTE: this could be moved move to `StackFrameFilename` - window.dispatchEvent(new CustomEvent("cell_highlight_range", { detail: { cell_id, from, to }})) - } - onmouseleave=${() => - window.dispatchEvent(new CustomEvent("cell_highlight_range", { detail: { cell_id, from: null, to: null }})) - } - > - ${message}@ - <${StackFrameFilename} frame=${{file: "#==#" + cell_id, line}} cell_id=${cell_id} /> -
  2. `) - } -
+
    + ${diagnostics.map( + ({ message, from, to, line }) => + html`
  1. + // NOTE: this could be moved move to `StackFrameFilename` + window.dispatchEvent(new CustomEvent("cell_highlight_range", { detail: { cell_id, from, to } }))} + onmouseleave=${() => + window.dispatchEvent(new CustomEvent("cell_highlight_range", { detail: { cell_id, from: null, to: null } }))} + > + ${message}@ + <${StackFrameFilename} frame=${{ file: "#==#" + cell_id, line }} cell_id=${cell_id} /> +
  2. ` + )} +
- `; + ` } export const ErrorMessage = ({ msg, stacktrace, cell_id }) => { @@ -102,9 +103,9 @@ export const ErrorMessage = ({ msg, stacktrace, cell_id }) => {
{ - e.preventDefault() - pluto_actions.split_remote_cell(cell_id, boundaries, true) - }} + e.preventDefault() + pluto_actions.split_remote_cell(cell_id, boundaries, true) + }} >Split this cell into ${boundaries.length} cells, or

` @@ -228,14 +229,13 @@ export const ErrorMessage = ({ msg, stacktrace, cell_id }) => { : html`
    ${stacktrace.map( - (frame) => - html`
  1. + (frame) => + html`
  2. <${Funccall} frame=${frame} /> @ <${StackFrameFilename} frame=${frame} cell_id=${cell_id} /> - ${frame.inlined ? html`[inlined]` : null}
  3. ` - )} + )}
`} ` diff --git a/src/runner/PlutoRunner/src/PlutoRunner.jl b/src/runner/PlutoRunner/src/PlutoRunner.jl index 2028b58039..624a16bcb0 100644 --- a/src/runner/PlutoRunner/src/PlutoRunner.jl +++ b/src/runner/PlutoRunner/src/PlutoRunner.jl @@ -1218,6 +1218,16 @@ end const has_julia_syntax = isdefined(Base, :JuliaSyntax) && fieldcount(Base.Meta.ParseError) == 2 +function frame_is_from_plutorunner(frame::Base.StackTraces.StackFrame) + if frame.linfo isa Core.MethodInstance + frame.linfo.def.module === PlutoRunner + else + endswith(String(frame.file), "PlutoRunner.jl") + end +end + +frame_is_from_usercode(frame::Base.StackTraces.StackFrame) = occursin("#==#", String(frame.file)) + function format_output(val::CapturedException; context=default_iocontext) if has_julia_syntax && val.ex isa Base.Meta.ParseError && val.ex.detail isa Base.JuliaSyntax.ParseError dict = convert_parse_error_to_dict(val.ex.detail) @@ -1230,21 +1240,23 @@ function format_output(val::CapturedException; context=default_iocontext) # function_wrap_index = findfirst(f -> occursin("function_wrapped_cell", String(f.func)), stack) - function_wrap_index = findlast(f -> occursin("#==#", String(f.file)), stack) - - if function_wrap_index === nothing - for _ in 1:2 - until = findfirst(b -> b.func == :eval, reverse(stack)) - stack = until === nothing ? stack : stack[1:end - until] - end + function_wrap_index = findlast(frame_is_from_usercode, stack) + internal_index = findfirst(frame_is_from_plutorunner, stack) + + limit = if function_wrap_index !== nothing + function_wrap_index + elseif internal_index !== nothing + internal_index - 1 else - stack = stack[1:function_wrap_index] + nothing end + stack_relevant = stack[1:something(limit, end)] - pretty = map(stack) do s + pretty = map(stack_relevant) do s Dict( :call => pretty_stackcall(s, s.linfo), :inlined => s.inlined, + :from_c => s.from_c, :file => basename(String(s.file)), :path => String(s.file), :line => s.line, @@ -1290,7 +1302,12 @@ end function pretty_stackcall(frame::Base.StackFrame, linfo::Core.MethodInstance) if linfo.def isa Method - sprint(Base.show_tuple_as_call, linfo.def.name, linfo.specTypes) + @static if isdefined(Base.StackTraces, :show_spec_linfo) && hasmethod(Base.StackTraces.show_spec_linfo, Tuple{IO, Base.StackFrame}) + sprint(Base.StackTraces.show_spec_linfo, frame; context=:backtrace => true) + + else + split(string(frame), " at ") |> first + end else sprint(Base.show, linfo) end