those two pieces of code results in the same error thrown given a condition:
function f1(x)
if x > 2
return x
else
return error("x <= 2")
end
end
function f2(x)
if x > 2
return x
else
throw(error("x <= 2"))
end
end
both f1
and f2
errors when x <= 2, but i can´t find any differences in why prefer one over the another. going further, these 3 pieces of code return the same:
error(2)
throw(2)
throw(error(2))
is there any guides on how to use throw vs return an error directly?
If the function is synchronous, you can either return some sentinel value that indicates an error and is easily distinguished from an actual result (often null in Javascript) or you can throw an exception or you can return an object that has a property that indicates the success or failure of the operation.
A return value that is greater than 0 indicates that there was a system error. The errno value returned by the system is returned by the function; for example, when a Berkeley DB function is unable to allocate memory, the return value from the function will be ENOMEM.
Throwing an error lets you indicate that something unexpected happened and the normal flow of execution can't continue. You use a throw statement to throw an error.
error
throws an error in itself. From the documentation:
error(message::AbstractString)
Raise an ErrorException with the given message.
So there is no need to either return it (as in your f1
function) or throw it yourself (as in f2
); in both cases the exception will be thrown by error
before your handwritten return
or throw
is even reached.
The same goes for your comparison between throw(error(2))
and error(2)
: the throw
is useless here and these two expressions should do the same thing (even the stack trace is the same).
Regarding error(2)
vs throw(2)
, it indeed superficially looks like they do the same thing (with slightly different stack traces):
julia> error(2)
ERROR: 2
Stacktrace:
[1] error(::Int64) at ./error.jl:42
[2] top-level scope at REPL[8]:1
julia> throw(2)
ERROR: 2
Stacktrace:
[1] top-level scope at REPL[10]:1
but this is only because the REPL pretty-prints the errors in ways that are indistinguishable in this case. In reality, throw
raises exactly what you pass it as argument: the integer 2 in this case. Whereas error
stringifies its argument and wraps it in an ErrorException
object before raising it. This can be seen by catching the exception and dump
ing it:
julia> try
error(2)
catch e
dump(e)
end
ErrorException
msg: String "2"
julia> try
throw(2)
catch e
dump(e)
end
Int64 2
In conclusion, I'd say
error
if you want to raise ErrorException
s, which are generic exceptions accompanied by a message as a string. This is IMO mostly adequate when the error is destined to a human. If you do so, only call error
; don't return
or throw
it.throw
when you want to control the type of exception raised. For example: throw(BoundsError(my_array, idx))
. Such an exception might be easier to catch and programmatically handle in some function up the stack. Or it will perhaps at least convey a more specific message to a user if it is not caught.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