diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index db6f5a26e90ed..78cd049905825 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -578,7 +578,11 @@ function print_response(repl::AbstractREPL, response, show_value::Bool, have_col return nothing end -function repl_display_error(errio::IO, @nospecialize errval) +# N.B.: Any functions starting with __repl_entry cut off backtraces when printing in the REPL. +__repl_entry_display(val) = Base.invokelatest(display, val) +__repl_entry_display(specialdisplay::Union{AbstractDisplay,Nothing}, val) = Base.invokelatest(display, specialdisplay, val) + +function __repl_entry_display_error(errio::IO, @nospecialize errval) # this will be set to true if types in the stacktrace are truncated limitflag = Ref(false) errio = IOContext(errio, :stacktrace_types_limited => limitflag) @@ -593,53 +597,59 @@ end function print_response(errio::IO, response, backend::Union{REPLBackendRef,Nothing}, show_value::Bool, have_color::Bool, specialdisplay::Union{AbstractDisplay,Nothing}=nothing) Base.sigatomic_begin() val, iserr = response - while true + if !iserr + # display result try - Base.sigatomic_end() - if iserr - val = Base.scrub_repl_backtrace(val) - Base.istrivialerror(val) || setglobal!(Base.MainInclude, :err, val) - repl_display_error(errio, val) - else - if val !== nothing && show_value - val2, iserr = if specialdisplay === nothing - # display calls may require being run on the main thread - call_on_backend(backend) do - Base.invokelatest(display, val) - end - else - call_on_backend(backend) do - Base.invokelatest(display, specialdisplay, val) - end + if val !== nothing && show_value + Base.sigatomic_end() # allow display to be interrupted + val2, iserr = if specialdisplay === nothing + # display calls may require being run on the main thread + call_on_backend(backend) do + __repl_entry_display(val) end - if iserr - println(errio, "Error showing value of type ", typeof(val), ":") - throw(val2) + else + call_on_backend(backend) do + __repl_entry_display(specialdisplay, val) end end - end - break - catch ex - if iserr - println(errio) # an error during printing is likely to leave us mid-line - println(errio, "SYSTEM (REPL): showing an error caused an error") - try - excs = Base.scrub_repl_backtrace(current_exceptions()) - setglobal!(Base.MainInclude, :err, excs) - repl_display_error(errio, excs) - catch e - # at this point, only print the name of the type as a Symbol to - # minimize the possibility of further errors. + Base.sigatomic_begin() + if iserr println(errio) - println(errio, "SYSTEM (REPL): caught exception of type ", typeof(e).name.name, - " while trying to handle a nested exception; giving up") + println(errio, "Error showing value of type ", typeof(val), ":") + val = val2 end - break end + catch ex + println(errio) + println(errio, "SYSTEM (REPL): showing a value caused an error") val = current_exceptions() iserr = true end end + if iserr + # print error + iserr = false + while true + try + Base.sigatomic_end() # allow stacktrace printing to be interrupted + val = Base.scrub_repl_backtrace(val) + Base.istrivialerror(val) || setglobal!(Base.MainInclude, :err, val) + __repl_entry_display_error(errio, val) + break + catch ex + println(errio) # an error during printing is likely to leave us mid-line + if !iserr + println(errio, "SYSTEM (REPL): showing an error caused an error") + val = current_exceptions() + iserr = true + else + println(errio, "SYSTEM (REPL): caught exception of type ", typeof(ex).name.name, + " while trying to print an exception; giving up") + break + end + end + end + end Base.sigatomic_end() nothing end