Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ function display_error(io::IO, er, bt)
end
display_error(er, bt=nothing) = display_error(stderr, er, bt)

# N.B.: Any functions starting with __repl_entry cut off backtraces when printing in the REPL.
__repl_entry_client_lower(mod::Module, @nospecialize(ast)) = Meta.lower(mod, ast)
__repl_entry_client_eval(mod::Module, @nospecialize(ast)) = Core.eval(mod, ast)

function eval_user_input(errio, @nospecialize(ast), show_value::Bool)
errcount = 0
lasterr = nothing
Expand All @@ -136,8 +140,8 @@ function eval_user_input(errio, @nospecialize(ast), show_value::Bool)
errcount = 0
lasterr = nothing
else
ast = Meta.lower(Main, ast)
value = Core.eval(Main, ast)
ast = __repl_entry_client_lower(Main, ast)
value = __repl_entry_client_eval(Main, ast)
setglobal!(Base.MainInclude, :ans, value)
if !(value === nothing) && show_value
if have_color
Expand Down
33 changes: 33 additions & 0 deletions test/client.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

import Base.StackTraces: StackFrame

nested_error_expr = quote
try
__not_a_binding__
Expand Down Expand Up @@ -57,3 +59,34 @@ end
@test eval(:(ans = 1)) == 1
@test eval(:(err = 1)) == 1
end

@testset "scrub REPL-related frames" begin
repl_bt = [StackFrame(:foo, "foo.jl", 1),
StackFrame(:__repl_entry_anysuffix, "client.jl", 2),
StackFrame(:bar, "bar.jl", 3)]
scrubbed_repl_bt = Base.scrub_repl_backtrace(repl_bt)

nonrepl_bt = [StackFrame(:foo, "foo.jl", 1),
StackFrame(:baz, "baz.jl", 2),
StackFrame(:bar, "bar.jl", 3)]
scrubbed_nonrepl_bt = Base.scrub_repl_backtrace(nonrepl_bt)

@test length(scrubbed_repl_bt) == 1
@test scrubbed_repl_bt[1].func == :foo
@test length(scrubbed_nonrepl_bt) == 3

errio = IOBuffer()
lower_errexpr = :(@bad)
Base.eval_user_input(errio, lower_errexpr, false)
outstr = String(take!(errio))
@test occursin("ERROR: LoadError: UndefVarError: `@bad`", outstr)
@test !occursin("_repl_entry", outstr)
@test !occursin(r"\.[/\\]client.jl", outstr)

errexpr = :(error("fail"))
Base.eval_user_input(errio, errexpr, false)
outstr = String(take!(errio))
@test occursin("ERROR: fail", outstr)
@test !occursin("_repl_entry", outstr)
@test !occursin(r"\.[/\\]client.jl", outstr)
end