Skip to content

Commit 1161406

Browse files
author
Christopher Doris
committed
better showerror overload
1 parent f243c65 commit 1161406

File tree

1 file changed

+69
-80
lines changed

1 file changed

+69
-80
lines changed

src/err.jl

Lines changed: 69 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ file_to_pymodule(fname::String) = begin
106106
end
107107
end
108108

109-
function Base.showerror(io::IO, e::PyException)
109+
Base.showerror(io::IO, e::PyException) = _showerror(io, e, nothing, backtrace=false)
110+
111+
Base.showerror(io::IO, e::PyException, bt; backtrace=true) = _showerror(io, e, bt; backtrace=backtrace)
112+
113+
function _showerror(io::IO, e::PyException, bt; backtrace=true)
110114
print(io, "Python: ")
111115

112116
if pyisnone(e.t)
@@ -125,108 +129,93 @@ function Base.showerror(io::IO, e::PyException)
125129
end
126130
end
127131

128-
# if this is a Julia exception then recursively print it and its stacktrace
129132
if !pyisnull(pyJuliaError) && pyissubclass(e.t, pyJuliaError)
133+
# handle Julia exceptions specially
130134
try
131-
# Extract error value
132135
je, jb = pyconvert(Tuple{Any,Any}, e.v.args)
133136
print(io, "Julia: ")
134-
# Show exception
135137
if je isa Exception
136-
showerror(io, je)
138+
showerror(io, je, jb, backtrace=backtrace && jb !== nothing)
137139
else
138140
print(io, je)
139-
end
140-
# Show backtrace
141-
if jb === nothing
142-
println(io)
143-
printstyled(io, "Stacktrace: none")
144-
else
145-
io2 = IOBuffer()
146-
Base.show_backtrace(
147-
IOContext(io2, io),
148-
jb,
149-
)
150-
printstyled(io, String(take!(io2)))
151-
end
152-
# Show Python backtrace
153-
if pyisnone(e.b)
154-
println(io)
155-
printstyled(io, "Python stacktrace: none")
156-
return
157-
else
158-
@goto pystacktrace
141+
backtrace && jb !== nothing && Base.show_backtrace(io, jb)
159142
end
160143
catch err
161144
println("<error while printing Julia exception inside Python exception: $err>")
162145
end
163-
end
164-
165-
# print the type name
166-
try
167-
print(io, e.t.__name__)
168-
catch err
169-
print(io, "<error while printing type: $err>")
170-
end
171-
172-
# print the error message
173-
if !pyisnone(e.v)
174-
print(io, ": ")
146+
else
147+
# print the type name
175148
try
176-
print(io, e.v)
149+
print(io, e.t.__name__)
177150
catch err
178-
print(io, "<error while printing value: $err>")
151+
print(io, "<error while printing type: $err>")
152+
end
153+
154+
# print the error message
155+
if !pyisnone(e.v)
156+
print(io, ": ")
157+
try
158+
print(io, e.v)
159+
catch err
160+
print(io, "<error while printing value: $err>")
161+
end
179162
end
180163
end
181164

182-
# print the stacktrace
183-
if !pyisnone(e.b)
184-
@label pystacktrace
165+
if backtrace
166+
# print the Python stacktrace
185167
println(io)
186168
printstyled(io, "Python stacktrace:")
187-
try
188-
fs = [(pystr(String, x.name), pystr(String, x.filename), pystr(String, x.lineno)) for x in pyimport("traceback").extract_tb(e.b)]
189-
if Base.VERSION < v"1.6.0-rc1"
190-
for (i, (name, fname, lineno)) in enumerate(reverse(fs))
191-
println(io)
192-
printstyled(io, " [", i, "] ")
193-
printstyled(io, name, bold = true)
194-
printstyled(io, " at ")
195-
printstyled(io, fname, ":", lineno, bold = true)
196-
end
197-
else
198-
mcdict = Dict{String, Symbol}()
199-
mccyclyer = Iterators.Stateful(Iterators.cycle(Base.STACKTRACE_MODULECOLORS))
200-
# skip a couple as a basic attempt to make the colours different from the Julia stacktrace
201-
popfirst!(mccyclyer)
202-
popfirst!(mccyclyer)
203-
for (i, (name, fname, lineno)) in enumerate(reverse(fs))
204-
println(io)
205-
printstyled(io, " [", i, "] ")
206-
printstyled(io, name, bold = true)
207-
println(io)
208-
printstyled(io, " @ ", color = :light_black)
209-
mod = file_to_pymodule(fname)
210-
if mod !== nothing
211-
# print the module, with colour determined by the top level name
212-
tmod = first(split(mod, ".", limit=2))
213-
color = get!(mcdict, tmod) do
214-
popfirst!(mccyclyer)
215-
end
216-
printstyled(io, mod, " ", color = color)
169+
if pyisnone(e.b)
170+
printstyled(io, " none")
171+
else
172+
try
173+
fs = [(pystr(String, x.name), pystr(String, x.filename), pystr(String, x.lineno)) for x in pyimport("traceback").extract_tb(e.b)]
174+
if Base.VERSION < v"1.6.0-rc1"
175+
for (i, (name, fname, lineno)) in enumerate(reverse(fs))
176+
println(io)
177+
printstyled(io, " [", i, "] ")
178+
printstyled(io, name, bold = true)
179+
printstyled(io, " at ")
180+
printstyled(io, fname, ":", lineno, bold = true)
217181
end
218-
if isfile(fname) && :stacktrace_contract_userdir in names(Base, all=true) && Base.stacktrace_contract_userdir()
219-
if :replaceuserpath in names(Base, all=true)
220-
fname = Base.replaceuserpath(fname)
221-
elseif :contractuser in names(Base.Filesystem, all=true)
222-
fname = Base.Filesystem.contractuser(fname)
182+
else
183+
mcdict = Dict{String, Symbol}()
184+
mccyclyer = Iterators.Stateful(Iterators.cycle(Base.STACKTRACE_MODULECOLORS))
185+
# skip a couple as a basic attempt to make the colours different from the Julia stacktrace
186+
popfirst!(mccyclyer)
187+
popfirst!(mccyclyer)
188+
for (i, (name, fname, lineno)) in enumerate(reverse(fs))
189+
println(io)
190+
printstyled(io, " [", i, "] ")
191+
printstyled(io, name, bold = true)
192+
println(io)
193+
printstyled(io, " @ ", color = :light_black)
194+
mod = file_to_pymodule(fname)
195+
if mod !== nothing
196+
# print the module, with colour determined by the top level name
197+
tmod = first(split(mod, ".", limit=2))
198+
color = get!(mcdict, tmod) do
199+
popfirst!(mccyclyer)
200+
end
201+
printstyled(io, mod, " ", color = color)
202+
end
203+
if isfile(fname) && :stacktrace_contract_userdir in names(Base, all=true) && Base.stacktrace_contract_userdir()
204+
if :replaceuserpath in names(Base, all=true)
205+
fname = Base.replaceuserpath(fname)
206+
elseif :contractuser in names(Base.Filesystem, all=true)
207+
fname = Base.Filesystem.contractuser(fname)
208+
end
223209
end
210+
printstyled(io, fname, ":", lineno, color = :light_black)
224211
end
225-
printstyled(io, fname, ":", lineno, color = :light_black)
226212
end
213+
catch err
214+
print(io, "<error while printing stacktrace: $err>")
227215
end
228-
catch err
229-
print(io, "<error while printing stacktrace: $err>")
230216
end
217+
218+
# print the Julia stacktrace
219+
Base.show_backtrace(io, bt)
231220
end
232221
end

0 commit comments

Comments
 (0)