Attach additional information to exception

If I want to attach additional information to an exception, e.g. I have a vector of some structs and do something with each. For one, there is an exception, and it would be helpful if I know from which.

Maybe like this:

julia> try
           try
             Int64(NaN)
         catch e
             error("Error from struct 1")
         end
       catch e2
           error("Error 2")
       end
ERROR: "Error 2"
Stacktrace:
 [1] top-level scope
   @ REPL[9]:8

caused by: "Error from struct 1"
Stacktrace:
 [1] top-level scope
   @ REPL[9]:5

caused by: InexactError: Int64(NaN)
Stacktrace:
 [1] Int64(x::Float64)
   @ Base .\float.jl:900
 [2] top-level scope
   @ REPL[9]:3

Is there an idiomatic way for this?

Mixing logging and exceptions is an option too:

try
    Int64(NaN)
catch e
    @debug("Error from struct 1")
    throw(e)
end

Your best bet is to define your own exception types.

julia> struct MyException <: Exception
           arg
       end

julia> throw(MyException(1))
ERROR: MyException(1)

This is just a plain struct, so it can have arbitrary number of fields, and of couse the fields can have type specifiers as well.

3 Likes

How would I then know the root cause?

I guess this is the correct way: GitHub - JuliaServices/ExceptionUnwrapping.jl: "I started by producing, and the rapping came second to that, because I wanted to fill out the beat." - Awkwafina

struct FooException{T} <: Base.Exception
    captured_exception::T
    msg::String
end

You don’t need to explicitly capture the root cause, Julia takes care of that for you when you throw an exception from a catch block. You can fetch the stack of exceptions with Base.current_exceptions(), where you will find not only your custom exception, but the root cause(s) as well.