diff --git a/frontend/components/ErrorMessage.js b/frontend/components/ErrorMessage.js
index c980ef119..369b79e6e 100644
--- a/frontend/components/ErrorMessage.js
+++ b/frontend/components/ErrorMessage.js
@@ -32,7 +32,7 @@ const DocLink = ({ frame }) => {
     if (frame.parent_module == null) return null
     if (ignore_funccall(frame)) return null
 
-    const funcname = frame.call.split("(")[0]
+    const funcname = frame.func
     if (funcname === "") return null
 
     const nb = pluto_actions.get_notebook()
@@ -88,39 +88,62 @@ const at = html`<span> from </span>`
 const ignore_funccall = (frame) => frame.call === "top-level scope"
 const ignore_location = (frame) => frame.file === "none"
 
+const funcname_args = (call) => {
+    const anon_match = call.indexOf(")(")
+    if (anon_match != -1) {
+        return [call.substring(0, anon_match + 1), call.substring(anon_match + 1)]
+    } else {
+        const bracket_index = call.indexOf("(")
+        if (bracket_index != -1) {
+            return [call.substring(0, bracket_index), call.substring(bracket_index)]
+        } else {
+            return [call, ""]
+        }
+    }
+}
+
 const Funccall = ({ frame }) => {
-    if (ignore_funccall(frame)) return null
+    let [expanded_state, set_expanded] = useState(false)
+    useEffect(() => {
+        set_expanded(false)
+    }, [frame])
 
-    const bracket_index = frame.call.indexOf("(")
+    const silly_to_hide = (frame.call_short.match(/…/g) ?? "").length <= 1 && frame.call.length < frame.call_short.length + 7
 
-    let inner =
-        bracket_index != -1
-            ? html`<strong>${frame.call.substr(0, bracket_index)}</strong><${ClickToExpandIfLong} text=${frame.call.substr(bracket_index)} />`
-            : html`<strong>${frame.call}</strong>`
+    const expanded = expanded_state || (frame.call === frame.call_short && frame.func === funcname_args(frame.call)[0]) || silly_to_hide
 
-    return html`<mark>${inner}</mark>`
-}
+    if (ignore_funccall(frame)) return null
 
-const LIMIT_LONG = 200,
-    LIMIT_PREVIEW = 100
+    const call = expanded ? frame.call : frame.call_short
 
-const ClickToExpandIfLong = ({ text }) => {
-    let [expanded, set_expanded] = useState(false)
+    const call_funcname_args = funcname_args(call)
+    const funcname = expanded ? call_funcname_args[0] : frame.func
 
-    useEffect(() => {
-        set_expanded(false)
-    }, [text])
+    // if function name is #12 or #15#16 then it is an anonymous function
 
-    const collaped_text = html`${text.slice(0, LIMIT_PREVIEW)}<a
-            href="#"
-            onClick=${(e) => {
-                e.preventDefault()
-                set_expanded(true)
-            }}
-            >...Show more...</a
-        >${text.slice(-1)}`
+    const funcname_display = funcname.match(/^#\d+(#\d+)?$/)
+        ? html`<abbr title="A (mini-)function that is defined without the 'function' keyword, but using -> or 'do'.">anonymous function</abbr>`
+        : funcname
+    console.log(funcname, funcname.match(/^#\d+(#\d+)?$/), funcname_display)
+
+    let inner = html`<strong>${funcname_display}</strong><${HighlightCallArgumentNames} code=${call_funcname_args[1]} />`
+
+    const id = useMemo(() => Math.random().toString(36).substring(7), [frame])
 
-    return html`<span>${expanded ? text : text.length < LIMIT_LONG ? text : collaped_text}</span>`
+    return html`<mark id=${id}>${inner}</mark> ${!expanded
+            ? html`<a
+                  aria-expanded=${expanded}
+                  aria-controls=${id}
+                  title="Display the complete type information of this function call"
+                  role="button"
+                  href="#"
+                  onClick=${(e) => {
+                      e.preventDefault()
+                      set_expanded(true)
+                  }}
+                  >...show types...</a
+              >`
+            : null}`
 }
 
 const LinePreview = ({ frame, num_context_lines = 2 }) => {
@@ -172,6 +195,19 @@ const JuliaHighlightedLine = ({ code, frameLine, i }) => {
     ></code>`
 }
 
+const HighlightCallArgumentNames = ({ code }) => {
+    const code_ref = useRef(/** @type {HTMLPreElement?} */ (null))
+    useLayoutEffect(() => {
+        if (code_ref.current) {
+            const html = code.replaceAll(/([^():{},; ]*)::/g, "<span class='argument_name'>$1</span>::")
+
+            code_ref.current.innerHTML = html
+        }
+    }, [code_ref.current, code])
+
+    return html`<s-span ref=${code_ref} class="language-julia"></s-span>`
+}
+
 const insert_commas_and_and = (/** @type {any[]} */ xs) => xs.flatMap((x, i) => (i === xs.length - 1 ? [x] : i === xs.length - 2 ? [x, " and "] : [x, ", "]))
 
 export const ParseError = ({ cell_id, diagnostics }) => {
@@ -218,7 +254,7 @@ 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)
+    const [funcname, params] = funcname_args(frame.call)
 
     if (["_collect", "collect_similar", "iterate", "error", "macro expansion"].includes(funcname)) {
         return false
diff --git a/frontend/treeview.css b/frontend/treeview.css
index e4fa55fa8..31fbfc2ee 100644
--- a/frontend/treeview.css
+++ b/frontend/treeview.css
@@ -317,6 +317,14 @@ jlerror > section .classical-frame > mark {
 jlerror > section .classical-frame > mark > strong {
     color: var(--black);
 }
+jlerror > section .classical-frame s-span {
+    /* color: var(--cm-color-type); */
+}
+jlerror > section .classical-frame s-span .argument_name {
+    color: var(--jlerror-mark-color);
+    color: var(--cm-color-var);
+    color: var(--cm-color-type);
+}
 jlerror > section .frame-source {
     display: flex;
     flex-direction: row;
diff --git a/src/runner/PlutoRunner/src/display/Exception.jl b/src/runner/PlutoRunner/src/display/Exception.jl
index 835c500ce..66e7e1b76 100644
--- a/src/runner/PlutoRunner/src/display/Exception.jl
+++ b/src/runner/PlutoRunner/src/display/Exception.jl
@@ -60,12 +60,16 @@ function format_output(val::CapturedException; context=default_iocontext)
         stack_relevant = stack[1:something(limit, end)]
 
         pretty = map(stack_relevant) do s
+            func = s.func === nothing ? nothing : s.func isa Symbol ? String(s.func) : repr(s.func)
             method = method_from_frame(s)
             sp = source_package(method)
             pm = VERSION >= v"1.9" && method isa Method ? parentmodule(method) : nothing
+            call = replace(pretty_stackcall(s, s.linfo), r"Main\.var\"workspace#\d+\"\." => "")
 
             Dict(
-                :call => replace(pretty_stackcall(s, s.linfo), r"Main\.var\"workspace#\d+\"\." => ""),
+                :call => call,
+                :call_short => type_depth_limit(call, 0),
+                :func => func,
                 :inlined => s.inlined,
                 :from_c => s.from_c,
                 :file => basename(String(s.file)),
@@ -124,6 +128,16 @@ function pretty_stackcall(frame::Base.StackFrame, linfo::Module)
 end
 
 
+function type_depth_limit(call::String, n::Int)
+    !occursin("{" , call) && return call
+    @static if isdefined(Base, :type_depth_limit) && hasmethod(Base.type_depth_limit, Tuple{String, Int})
+        Base.type_depth_limit(call, n)
+    else
+        call
+    end
+end
+
+
 "Because even showerror can error... 👀"
 function try_showerror(io::IO, e, args...)
     try