Skip to content

Commit

Permalink
Stack trace tweaks part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsp committed Oct 3, 2024
1 parent 7c39672 commit 99cf0e4
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 21 deletions.
96 changes: 81 additions & 15 deletions frontend/components/ErrorMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { html, useContext, useEffect, useLayoutEffect, useRef, useState } from "
import { highlight } from "./CellOutput.js"
import { PkgTerminalView } from "./PkgTerminalView.js"
import _ from "../imports/lodash.js"
import { open_bottom_right_panel } from "./BottomRightPanel.js"

const extract_cell_id = (/** @type {string} */ file) => {
const sep_index = file.indexOf("#==#")
Expand All @@ -24,30 +25,59 @@ const focus_line = (cell_id, line) =>
})
)

const DocLink = ({ frame }) => {
let pluto_actions = useContext(PlutoActionsContext)

if (frame.parent_module == null) return null
if (ignore_funccall(frame)) return null

const nb = pluto_actions.get_notebook()

const pkg_name = frame.source_package
const builtin = ["Main", "Core", "Base"].includes(pkg_name)
const installed = nb?.nbpkg?.installed_versions?.[frame.source_package] != null

if (!builtin && nb?.nbpkg != null && !installed) return null

return html`  <span
><a
href="#"
class="doclink"
onClick=${(e) => {
e.preventDefault()
open_bottom_right_panel("docs")
pluto_actions.set_doc_query(`${frame.parent_module}.${frame.call.split("(")[0]}`)
}}
>docs</a
></span
>`
}

const StackFrameFilename = ({ frame, cell_id }) => {
if (ignore_location(frame)) return null

const frame_cell_id = extract_cell_id(frame.file)
if (frame_cell_id != null) {
const a = html`<a
return html`<a
internal-file=${frame.file}
href=${`#${frame_cell_id}`}
onclick=${(e) => {
focus_line(frame_cell_id, frame.line - 1)
e.preventDefault()
}}
>
${frame_cell_id == cell_id ? "This\xa0cell" : "Other\xa0cell"}: line ${frame.line}
${frame_cell_id == cell_id ? "This\xa0cell" : "Other\xa0cell"}<em>line ${frame.line}</em>
</a>`
return html`<em>${a}</em>`
} else {
const sp = frame.source_package
const origin = ["Main", "Core", "Base"].includes(sp) ? "julia" : sp

const text = sp != null ? html`<strong>${origin}</strong> → ${frame.file}` : frame.file
const file_line = html`<em>${frame.file}:${frame.line}</em>`

const text = sp != null ? html`<strong>${origin}</strong> → ${file_line}` : file_line

const href = frame?.url?.startsWith?.("https") ? frame.url : null
return html`<em title=${frame.path}><a class="remote-url" href=${href}>${text}:${frame.line}</a></em>`
return html`<a title=${frame.path} class="remote-url" href=${href}>${text}</a>`
}
}

Expand All @@ -66,26 +96,29 @@ const Funccall = ({ frame }) => {
? html`<strong>${frame.call.substr(0, bracket_index)}</strong><${ClickToExpandIfLong} text=${frame.call.substr(bracket_index)} />`
: html`<strong>${frame.call}</strong>`

return html`<mark>${inner}</mark>${at}`
return html`<mark>${inner}</mark>`
}

const LIMIT_LONG = 200,
LIMIT_PREVIEW = 100

const ClickToExpandIfLong = ({ text }) => {
let [expanded, set_expanded] = useState(false)

useEffect(() => {
set_expanded(false)
}, [text])

const collaped_text = html`${text.slice(0, 250)}<a
const collaped_text = html`${text.slice(0, LIMIT_PREVIEW)}<a
href="#"
onClick=${(e) => {
e.preventDefault()
set_expanded(true)
}}
>...more...</a
>...Show more...</a
>${text.slice(-1)}`

return html`<span> ${expanded ? text : text.length < 300 ? text : collaped_text} </span>`
return html`<span>${expanded ? text : text.length < LIMIT_LONG ? text : collaped_text}</span>`
}

const LinePreview = ({ frame, num_context_lines = 2 }) => {
Expand Down Expand Up @@ -161,15 +194,19 @@ export const ParseError = ({ cell_id, diagnostics }) => {
${diagnostics.map(
({ message, from, to, line }) =>
html`<li
class="from_this_notebook from_this_cell"
class="from_this_notebook from_this_cell important"
onmouseenter=${() =>
// 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 } }))}
>
<div class="classical-frame">
${message}${at}<${StackFrameFilename} frame=${{ file: "#==#" + cell_id, line }} cell_id=${cell_id} />
${message}
<div class="frame-source">
${at}
<${StackFrameFilename} frame=${{ file: "#==#" + cell_id, line }} cell_id=${cell_id} />
</div>
</div>
</li>`
)}
Expand All @@ -179,6 +216,29 @@ export const ParseError = ({ cell_id, diagnostics }) => {
`
}

const frame_is_important_heuristic = (frame, frame_index, limited_stacktrace, frame_cell_id) => {
if (frame_cell_id != null) return true

const [funcname, params] = frame.call.split("(", 2)

if (["_collect", "collect_similar", "iterate", "error", "macro expansion"].includes(funcname)) {
return false
}

if (params == null) {
// no type signature... must be some function call that got optimized away or something special
// probably not directly relevant
return false
}

if ((funcname.match(/#/g) ?? "").length >= 2) {
// anonymous function: #plot#142
return false
}

return true
}

export const ErrorMessage = ({ msg, stacktrace, cell_id }) => {
let pluto_actions = useContext(PlutoActionsContext)
const default_rewriter = {
Expand Down Expand Up @@ -371,20 +431,26 @@ export const ErrorMessage = ({ msg, stacktrace, cell_id }) => {
</div>
<ol>
${limited_stacktrace.map((frame) => {
${limited_stacktrace.map((frame, frame_index) => {
const frame_cell_id = extract_cell_id(frame.file)
const from_this_notebook = frame_cell_id != null
const from_this_cell = cell_id === frame_cell_id
return html`<li class=${cl({ from_this_notebook, from_this_cell })}>
const important = frame_is_important_heuristic(frame, frame_index, limited_stacktrace, frame_cell_id)
return html`<li class=${cl({ from_this_notebook, from_this_cell, important })}>
<div class="classical-frame">
<${Funccall} frame=${frame} />
<${StackFrameFilename} frame=${frame} cell_id=${cell_id} />
<div class="frame-source">
${at}
<${StackFrameFilename} frame=${frame} cell_id=${cell_id} />
<${DocLink} frame=${frame} />
</div>
</div>
${from_this_notebook ? html`<${LinePreview} frame=${frame} num_context_lines=${from_this_cell ? 1 : 2} />` : null}
</li>`
})}
${limited
? html`<li>
? html`<li class="important">
<a
href="#"
onClick=${(e) => {
Expand Down
25 changes: 19 additions & 6 deletions frontend/treeview.css
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,18 @@ jlerror > section > ol {
/* transform-origin: top; */
/* perspective-origin: top; */
}
jlerror > section > ol > li {
margin-block-end: 1em;
}

jlerror > section > ol > li:not(.important):not(:hover) {
opacity: 0.5;
}
jlerror > section > ol > li.from_this_notebook {
--bg: var(--jl-info-acccolor);
background: var(--bg);
outline: 3px solid var(--bg);
padding: 0.4em 0.2em;
padding: 0.4em 0em;
border-radius: 0.6em;
}
jlerror > section .classical-frame > mark {
Expand All @@ -302,24 +309,30 @@ jlerror > section .classical-frame > mark {
jlerror > section .classical-frame > mark > strong {
color: var(--black);
}
jlerror > section .classical-frame > em > a {
jlerror > section .frame-source {
display: flex;
flex-direction: row;
align-items: baseline;
/* justify-content: flex-end; */
}
jlerror > section .frame-source > a {
background: var(--jlerror-a-bg-color);
border-radius: 4px;
padding: 1px 7px;
text-decoration: none;
border-left: 3px solid var(--jlerror-a-border-left-color);
/* font-family: var(--system-ui-font-stack); */
}
jlerror > section .classical-frame > em > a:not([href]) {
jlerror > section .frame-source > a:not([href]) {
filter: grayscale(1);
}
jlerror > section .classical-frame > em > a[href].remote-url {
jlerror > section .frame-source > a[href].remote-url {
filter: hue-rotate(160deg);
}
jlerror > section li.from_this_notebook:not(.from_this_cell) .classical-frame > em > a[href] {
jlerror > section li.from_this_notebook:not(.from_this_cell) .frame-source > a[href] {
filter: hue-rotate(50deg);
}
jlerror > section .classical-frame > span {
jlerror > section .frame-source > span {
opacity: 0.4;
padding: 0px 0.2em;
}
Expand Down
2 changes: 2 additions & 0 deletions src/runner/PlutoRunner/src/display/Exception.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function format_output(val::CapturedException; context=default_iocontext)
pretty = map(stack_relevant) do s
method = method_from_frame(s)
sp = source_package(method)
pm = method isa Method ? parentmodule(method) : nothing

Dict(
:call => pretty_stackcall(s, s.linfo),
Expand All @@ -73,6 +74,7 @@ function format_output(val::CapturedException; context=default_iocontext)
:linfo_type => string(typeof(s.linfo)),
:url => frame_url(method),
:source_package => sp === nothing ? nothing : string(sp),
:parent_module => pm === nothing ? nothing : string(pm),
)
end
else
Expand Down

0 comments on commit 99cf0e4

Please sign in to comment.