difference between throw an error and return an error in julia

Viewed 1160

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?

1 Answers

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 dumping 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

  • use error if you want to raise ErrorExceptions, 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.
  • use 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.
Related