2

I am trying to get an error message of a caught exception for use in a warning.

For example, while following

julia> a = 3+b
ERROR: UndefVarError: b not defined
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

says that the problem is that b is not defined, the following method of handling exception has much less helpful message:

julia> try
           a = 3+b
       catch e
           @warn "Bad thing happend: $e"
       end
┌ Warning: Bad thing happend: UndefVarError(:b)
└ @ Main REPL[2]:4

How do I get the error message and stacktrace from the exception as String?

BoZenKhaa
  • 782
  • 1
  • 6
  • 22

1 Answers1

2

While a bit wordy, the answer seems to be by using the Base.showerror(io::IO, err::MyException) function defined for builtin exceptions:

julia> try
           a = 3+b
       catch e
           io = IOBuffer();
           showerror(io, e)
           error_msg = String(take!(io))
           @warn "Trouble doing things:\n$(error_msg)"
       end
┌ Warning: Trouble doing things:
│ UndefVarError: b not defined
└ @ Main REPL[3]:7

To also get the stacktrace:

  1. use stacktrace(catch_backtrace()) to get the stacktrace vector from the place exception was thrown (see docs)
  2. use show(io, mime, x) to format the vector nicely (see this SO answer)

Combining the two with the sprint that handles the IOBuffer for us, we get to:

julia> try
           a = 3+b
       catch e
           error_msg = sprint(showerror, e)
           st = sprint((io,v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
           @warn "Trouble doing things:\n$(error_msg)\n$(st)"
       end
┌ Warning: Trouble doing things:
│ UndefVarError: b not defined
│ 13-element Vector{Base.StackTraces.StackFrame}:
│  top-level scope at REPL[4]:2
│  eval at boot.jl:373 [inlined]
│  ...
└ @ Main REPL[4]:6
BoZenKhaa
  • 782
  • 1
  • 6
  • 22