I’m not really sure if this is the right place for this question, so please let me know where I should be if this is not the right place.
I’m new to Julia, and I am writing some scripts that I’d like to use from the Linux command line. This works all fine, but when I included some exception handling into my script I found that that whenever I throw an exception Julia throws an additional LoadError So for example if I run a script containing only the following line:
throw(DivideError())
I get the both a DivideError (which I want) and a LoadError (Which I don’t want) when I run the script:
$ julia throwError.jl
ERROR: LoadError: DivideError: integer division error
Stacktrace:
[1] top-level scope at /path/throwError.jl:1
[2] include(::Function, ::Module, ::String) at ./Base.jl:380
[3] include(::Module, ::String) at ./Base.jl:368
[4] exec_options(::Base.JLOptions) at ./client.jl:296
[5] _start() at ./client.jl:506
in expression starting at /path/throwError.jl:1
Can somebody explain what is happening here, and how I can prevent the LoadError?
Hi Jonas! You provided a concise example, which makes it so much easier to help.
Julia runs the code in order to load it. If you put the throw() inside a function, then Julia will run the function definition, but it won’t run the function that gets defined. You won’t see the DivideError until later, when you call the function. So:
function suspicious_fry(x)
throw(DivideError())
x
end
Thank you for your answer. It is not so much that I have a problem, it’s more that I try to understand how Julia works. For me throwing exceptions works fine. I was just wondering why the DivideError is wrapped by a LoadError.
Putting the throw() inside a function changes the stacktrace slightly but doesn’t change the error that is thrown. I asked this question as well on stackoverflow and somebody there pointed me to this pull request on github. What I understood from it is that Julia wraps exception throws in a LoadError as a way to show the stacktrace, but that they hope to deprecate this behavior at some point by improving backtracing in general.
But maybe somebody who has a better understanding of this, can phrase it more clearly than me.
Hi Aldogert, Thanks for your code example. It made things more me clear for me.
However, I still think its peculiar that the catch y throw(LoadError(y)) is/was necessary to show the line numbers in the stack trace (at least that is what I understood from the PR).
second.jl throws the exception only if the global run flag is set:
function panic_at_the_disco()
throw(DivideError())
end
if run == true
panic_at_the_disco()
end
The main file (first.jl):
run = false
include("second.jl")
try
println("*******************************")
println("Calling panic...")
panic_at_the_disco()
catch ex
println("Exception caught: $(typeof(ex))")
println()
end
try
println("*******************************")
println("Running panic during include...")
global run = true
include("second.jl")
catch ex
println("Exception caught: $(typeof(ex))")
if ex isa LoadError
println("Caused by: $(typeof(ex.error))")
end
println()
end