Skip to content

0003: making error backtrace explicitly tied to catch

Jameson Nash edited this page Jan 6, 2017 · 1 revision

ref: https://github.com/JuliaLang/julia/issues/7633#issuecomment-49350131

type ExceptionData <: Exception
  error::Exception
  backtrace::Array{Any}
end
ExceptionData(err) = ExceptionData(err, {})
try
  error("something went wrong here")
catch err, bt
  rethrow(err,bt) # -> propagates an `ExceptionData(err, bt)` object
end
# code_lowered:
    $(Expr(:enter, 0, true)) # true means we need the backtrace
    `#s118` = error()
    $(Expr(:leave, 1))
    return `#s118`
    0: 
    $(Expr(:leave, 1))
    e = $(Expr(:the_exception))
    bt = $(Expr(:the_backtrace)) # returns a copy of the backtrace
    return rethrow(e,bt)
try
  error("something went wrong here")
catch err
  rethrow(err) # -> propagates `err`
end
# code_lowered:
    $(Expr(:enter, 0, false)) # false means we don't need the backtrace
    `#s118` = error()
    $(Expr(:leave, 1))
    return `#s118`
    0: 
    $(Expr(:leave, 1))
    e = $(Expr(:the_exception))
    return rethrow(e)
try
  error("something went wrong here")
finally
  rethrow(err) # -> propagates `err`
end
# code_lowered:
    #s120 = false
    $(Expr(:enter, 1)) # no parameter means inherit the backtrace-need from the previous exception frame
    `#s117` = error()
    $(Expr(:leave, 1))
    goto 2
    1: 
    $(Expr(:leave, 1))
    `#s120` = true
    `#e` = $(Expr(:the_exception))
    `#bt` = $(Expr(:the_backtrace)) # returns a copy of the backtrace
    2: 
    0:
    unless `#s120` goto 3
    top(ccall)(:jl_rethrow,Void,top(tuple)(Any, Any),`#e`,`#bt`)
    3: 
    return `#s117`
try
  error("something went wrong here")
catch err...
  rethrow(err...)
end
# code_lowered:
    $(Expr(:enter, 0)) # no parameter means inherit the backtrace-need from the previous exception frame
    `#s118` = error()
    $(Expr(:leave, 1))
    return `#s118`
    0: 
    $(Expr(:leave, 1))
    e = ($(Expr(:the_exception)), $(Expr(:the_backtrace)))
    # `e` is a tuple of the exception and copy of the backtrace (which might return {} if we didn't create a backtrace)
    return rethrow(e...)