Suppose I have the code,
try
throw(ArgumentError("hi"))
catch
println("something went wrong")
throw(ArgumentError("bye"))
end
Running this code results in the following output
something went wrong
ERROR: ArgumentError: bye
Stacktrace:
[1] top-level scope at REPL[31]:5
caused by [exception 1]
ArgumentError: hi
Stacktrace:
[1] top-level scope at REPL[31]:2
Basically, it throws both the error in the try
block and the error in the catch
block.
My understanding of how things should work is that try
should fail, and then it should simply output what's inside the catch
block.
Can anyone explain what is going on here, and how to rewrite this code so it has the desired functionality.
Thanks.
What happens is exactly what you describe, only the exception thrown by throw(ArgumentError("bye"))
goes out of the try
-catch
block.
The thing you see is caused by the fact that if you have such an "exception caused by exception" Julia prints out whole exception stack via show_exception_stack
from base/errorshow.jl. In this way you learn that the exception thrown in catch
block was caused by the exception thrown in try
block. But this is only for display purposes.
You can check this by wrapping your code in another try
-catch
block and investigating what exception goes out from the inner try
-catch
:
julia> try
try
throw(ArgumentError("hi"))
catch
println("something went wrong")
throw(ArgumentError("bye"))
end
catch e
dump(e)
end
something went wrong
ArgumentError
msg: String "bye"
julia>
You might also want to look at rethrow()
. The helpstring explains the behavior you're seeing:
(This documentation comes from Julia 1.4): https://docs.julialang.org/en/v1.4-dev/base/base/#Base.rethrow
help?> rethrow
search: rethrow
rethrow()
Rethrow the current exception from within a catch block. The rethrown exception will continue propagation as if it had not been caught.
│ Note
│
│ The alternative form rethrow(e) allows you to associate an alternative exception object e with the current backtrace. However this misrepresents the program state
│ at the time of the error so you're encouraged to instead throw a new exception using throw(e). In Julia 1.1 and above, using throw(e) will preserve the root cause
│ exception on the stack, as described in catch_stack.
In particular: In Julia 1.1 and above, using throw(e) will preserve the root cause exception on the stack, as described in catch_stack.
If you just want to print something before the original exception is propagated, you can use no-argument rethrow()
:
julia> try
throw(ArgumentError("hi"))
catch
println("something went wrong")
rethrow()
end
something went wrong
ERROR: ArgumentError: hi
Stacktrace:
[1] top-level scope at REPL[9]:2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With