When ArgumentError should be thrown?

Recently, I had a chance to review error handling of a package and I found many error checking lines are throwing ArgumentError but in various reasons. Some lines are complaining about a argument value, some lines are about argument types, some lines are saying even an argument is not supported yet.

However, when I check the help document about ArgumentError, I can see:

The parameters to a function call do not match a valid signature. Argument msg is a descriptive error string.

So, the document is saying you can throw the exception in a case of mismatched signature. Wait! How can the method be called if its signature is not matched? In fact, none of the code lines I saw threw the exception for the purpose.

I have a feeling that ArgumentError has been abused so far without clear instructions. If you are a Julia expert, would you tell me exactly when the exception should be thrown? Also appreciate if somebody updates the help document with more details.

I guess it is just wording. Maybe “valid arguments” would be better.

Exceptions do not have strict rules in this sense, unless you want to capture a particular one (then of course you should be specific). I think the best approach is to make it easy for the user to understand what went wrong, in case the exception is not caught (which is most of the time for generic exceptions).

Other than that, try to use the most specific one applicable, eg a BoundsError should be used instead of an ArgumentError in case something getindex-like goes wrong, etc.

Consider making a PR.

Thanks for the advice, @Tamas_Papp

Agree. “valid arguments” makes more sense.

Over the past experience with other languages, I learned I should be very careful in selecting its type when raising an exception. The raised exception can be captured and handled by any programs using my code. However, I found even some mature Julia packages still have code lines just calling error() or throwing ArgumentError even when there is an obvious choice of a more specific built-in exception e.g. BoundsError. Considering a raised Exception is also a part of a method’s API, I cautiously propose that when raising and handling exceptions, a more disciplined approach would be desirable to Julia community.

Not sure if I can make any suggestion but at least I will create an issue for it.

You make a valid point, but note that in Julia it is less common to use exceptions for control flow, because they are (relatively) expensive.

It is best to just open an issue for a particular function if you explicitly want to capture exceptions and need a more specific type.

For reference you might also want to have a look at this old thread: Please stop using `error` and `ErrorException` in packages (and Base). My general feeling from that thread was that there isn’t really a consensus on how exceptions should be used, though personally I don’t use them for flow control for the reason that Tamas laid out (expense).

1 Like