So, for language interop reasons, I’d like to translate Julia exceptions into a different kind of error. In the C API, it is pretty clear that jl_exception_occurred is what to use to check if an exception occurred or not. But, if an exception has occurred, I haven’t found it clear how to extract the error message from it. Some exceptions seem to have the msg field, but others (like DomainError) do not.
Is it possible to get the message of an arbitrary exception as a string? For DomainError thrown by sqrt(-1), this would be:
ERROR: DomainError:
sqrt will only return a complex result if called with a complex argument. Try sqrt(complex(x)).
in sqrt(::Int64) at ./math.jl:211
You can call sprint(showerror, e) to get the message of an exception in string form, or sprint(showerror, e, backtrace()) in the context of a catch block to print additional information extracted from the backtrace.
For example, the sqrt message you quoted is printed by a special case of showerror given a backtrace indicating that the DomainError came from a sqrt call.
try
sqrt(-1)
catch e
bt = backtrace()
msg = sprint(showerror, e, bt)
println(msg)
end
I don’t get the full error message, what I see is:
DomainError:
in backtrace() at ./error.jl:26
in backtrace() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in include_from_node1(::String) at ./loading.jl:488
in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in process_options(::Base.JLOptions) at ./client.jl:262
in _start() at ./client.jl:318
in _start() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
Ah, okay, so this does work (sort of, see below) if I use catch_backtrace() instead of backtrace(). However, if I try and encapsulate the whole thing in a function, it seems to no longer work.
To be clear, this works and gives me the full message:
try
sqrt(-1)
catch e
bt = catch_backtrace()
msg = sprint(showerror, e, bt)
println(msg)
end
Whereas this does not:
function test()
try
sqrt(-1)
catch e
bt = catch_backtrace()
msg = sprint(showerror, e, bt)
println(msg)
end
end
test()
By default Julia inlines most or all of the sqrt call when the block is inside a function. Hence the sqrt symbol is missing from the backtrace, and showerr doesn’t get the hint to add the detailed message. You could turn off inlining if you really want the message.