Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia throws error twice in try-catch block

Tags:

julia

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.

like image 444
Thoth Avatar asked Dec 31 '19 17:12

Thoth


2 Answers

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>
like image 70
Bogumił Kamiński Avatar answered Sep 27 '22 21:09

Bogumił Kamiński


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
like image 34
NHDaly Avatar answered Sep 27 '22 20:09

NHDaly