1

I suppose this question is valid for any programming language that can handle (or at least throw) an exception. However I will stick to Python as an example.

The top 2 answers to the following question disagree with each other on a particular point. https://stackoverflow.com/questions/2052390/manually-raising-throwing-an-exception-in-python

At this moment (2015 March 14 Sat 2354 hrs) it seems that there's a growing consensus around the second answer (Aaron Hall's answer in case any of this changes in the future). And I think I do get the point about being specific about the type of exception I am supposed to raise. A hierarchy for Python is given here: https://docs.python.org/3/library/exceptions.html#exception-hierarchy

Now, I am at point where I want to manually raise an exception when a division results in a non-integer. Specifically, I have a 2D array and I also have the number of columns in it. If the division of the former by the latter results in an non-integer, it means that the number of rows is a non-integer, and thus something's messed up somewhere. And I want to raise an exception.

Why would it be wrong to just include raise Exception("Something's wrong. Number of rows is not an integer!") in my code? The categories in the hierarchy are just words in English, but I am not able to choose the best category for my purpose. So what's wrong in clearly explaining the issue in my message (which for the present example is the problem that the number of rows is not an integer)?

4
  • Your exception should say something that means "the 2D table (of numbers) is malformed (corrupted) or truncated (incomplete).".
    – rwong
    Commented Mar 15, 2015 at 4:23
  • Also, it is acceptable to define your own exception types (suitable to your application) by inheriting from the base exception, or ValueError, as well as giving it a specific human-readable message.
    – rwong
    Commented Mar 15, 2015 at 4:32
  • But that's the question: how did you arrive at ValueError? I was conflicted between ArithmeticError and ValueError when I went through the hierarchy. Commented Mar 15, 2015 at 4:42
  • 1
    You will have to analyze the possible reasons why that situation (the two numbers being non-divisible) will happen. It requires logical thinking; if necessary, you may have to debate with yourself whether a certain "root cause" is probable or not. For example, if the 2D table is parsed from some other data source (such as a text file), the root cause could be a data formatting error (by the software that generates this file), a parsing error (in your own code), or the text file may have been truncated (during transmission or file handling).
    – rwong
    Commented Mar 15, 2015 at 4:50

2 Answers 2

3

You are creating a user interface -- code is a user interface, where the "user" is another programmer, or another function. If you were the user of your code rather than the developer, what would make your code easier to use? So, look at this problem from the perspective of someone calling your function. What would be the most useful exception you could give? Note: there may be more than one answer, in which case it really doesn't matter too much. The point is, make your code as easy to use as possible.

The other important thing to remember is this: you may be only sending one exception, but your code as a whole could be sending many. The exception you throw needs to play nicely with all of the other possible exceptions (meaning: it must be distinguishable from the other exceptions).

In this specific case (and in most cases...), a generic exception isn't particularly useful. There could be more than one way that your function fails. Maybe the inputs are floats instead of integers. Maybe they are strings. Or maybe the inputs result in a divide by zero. The caller may care about these distinctions. Maybe they won't, but they might. And if not now, they might in the future.

1

Raising a generic xception and differentiating it just by its message would be wrong because then, if you have many of them and want to react appropriately, how would you distinguish them?

Regarding the choice of the exception, taking your example, I would say that ArithmeticError is something pretty low-level and focused on the arithmetic aspects of the problem. In your case, is it an arithmetic error the fact that 7 is not divisible by 3? No, arithmetically it's correct.

That's a problem if taken from another point of view, namely the one of your application logic, so such exception would make sense only in your application. I would make my own one (e.g. NonDivisibleTableError derived from Exception).

Now, how could that happen? That's another issue, but a quick search showed that also in Python it's possible to specify a cause when throwing an exception (see raise/from). This way you can describe what went wrong at the different levels of your application, (e.g. NonDivisibleTableError caused by some IOError), and give the user a more reasoned error message.

Not the answer you're looking for? Browse other questions tagged or ask your own question.