Docs: error and exceptions explanation

I was reading the docs carefully, and this section seems confuse:

The section starts with the example of “Suppose we want to stop execution immediately if the square root of a negative number is taken.”, and defines a custom exception for a sqrt function, etc.

However, the standard sqrt also stops the execution immediately if the argument is negative (or it does not?).

Thus, it is not clear to me if the example is only showing the custom definition of an error message, or if there is something else under the hood that should be explained.

Similarly, it is not clear in the previous section, Throw function, which is the utility of defining custom exception errors, or even what exception types provide besides a different error message each. I guess that we can catch the type of error in a try block and deal with it later. In that case probably the Try section should come before that?

In the way it is organized and written, one has impression that standard exception errors will not stop the program immediately, and that one should read the output as something like r = sqrt(-1) ; if r isa(Error) etc, and if we wanted that they stop the program, a new custom error must be defined for the function in question.

Yes, it does, the documentation says so, and the REPL agrees with it:

  sqrt(x)

  Return \sqrt{x}. Throws DomainError for negative Real arguments. Use complex
  negative arguments instead. The prefix operator √ is equivalent to sqrt.

julia> sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).

It seems to me that, maybe, this section was written a long time ago, when sqrt did not throw? It could be updated to a less confusing example. But is even more strange because in the same page, a little above, inside section Built-in Exceptions the example of built-in exception is exactly it: “For example, the sqrt function throws a DomainError if applied to a negative real value:”

Yes, I think the main utilities are (i) being able to chose if capture or not based on the type of the exception and (ii) that you may write a constructor that just take some data and will assemble the string for you, on demand, if it needs to be shown.

It is possible that, for the beginner in a language with exceptions, it would be better to have the Try section before the throw section. It was probably an oversight in which the writers assumed the reader already had some familiarity with the topic.

What bugged me most in the throw section is the “Additionally, some exception types take one or more arguments that are used for error reporting:” that comes after all section already was using exception types with one or more arguments, it seems to me that someone re-wrote the examples above and forgot to remove or move this paragraph below.

I am not sure if I follow you train of thought. Just creating an exception is just creating an object of that type and no different than creating an instance of any other struct, what stops the execution and flows it to the innermost try-catch that encloses the code is calling throw.

1 Like

I just wanted to mean that, as written there, one might think that sqrt(-1) would return an exception message but that would not stop the execution, in such a way that we would have to decide what to do with that, as if every error in any internal function was implemented in a try block.

Cf

Perhaps the docs could be improved by calling it mysqrt, and just suggesting that this is how it can implemented (removing all references to “fussy”).