-3
\$\begingroup\$

Just looking for opinions on which is the best way to use exceptions?

Should the exception handling go inside the function or should it go outside the function when you actually call the function. For example, we could have the following function:

def divideMe(a,b):

     return a/b

This function is risky because there is a chance that if the calling program passes a value of 0 in for the argument b then the function would divide by zero and an exception would be raised. So the question is should you put the exception handling inside the function and handle it like this:

def divideMe(a,b):

     try:

          return a/b

     except Exception:

          return 0

OR should the calling program catch and handle the exception, like this:

try:

   result = divideMe(x,y)

except Exception:

   print("You entered 0 in for denominator")
\$\endgroup\$
1
  • \$\begingroup\$ Hi Alicia, unfortunately it's impossible to answer your question. I can make reasonable arguments that either are good - much like I'm sure you can, and is why you're asking this question. However deciding which is better comes down to the scenario that you're working in. And so to be able to even start thinking of answering this we'd need to know how and why it's being called. Since this is Code Review, if you have a situation that has brought about this question; then providing the calling function is likely to be received better. \$\endgroup\$ – Peilonrayz Feb 6 '20 at 20:24
1
\$\begingroup\$
In [3]: def divide(a, b):
   ...:     return a / b
   ...: 


In [5]: try:
   ...:     result = divide("a", 5)
   ...: except Exception:
   ...:     print("You entered 0 in for denominator")
   ...:     
You entered 0 in for denominator

See the problem? Exceptions were invented to release the libraries from the burden to guess what beahiour the user wants for all kind of errors. Libraries shall not print but leave it to the caller. The caller is the only one to know how to react on different kind of exceptions. So if you catch, be specific.

\$\endgroup\$
1
  • \$\begingroup\$ Please refrain from answering off-topic questions. \$\endgroup\$ – Peilonrayz Feb 6 '20 at 20:26
-1
\$\begingroup\$

Depends on what the function dose and what the error is, because the "divide" function dose division, and because the DevideByzero error is about division, the function should handle it, but if you were handling TypeErrors, for example that should be outside of the function.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Please refrain from answering low-quality questions that are likely to get closed. Once you've answered, that limits what can be done to improve the question, making it more likely that your efforts are wasted. It's better to wait until the question is properly ready before you answer! \$\endgroup\$ – Toby Speight Feb 6 '20 at 19:00
-1
\$\begingroup\$

As a general rule, you should allow exceptions to percolate back to the caller; this makes it easier for the caller to find bugs in their own code. A function should have a clear "contract" with its caller that will typically include raising an exception if the caller passes it invalid arguments. If part of your function's contract is that it will catch invalid arguments and return a default value in that case, make sure that's explicit in the docstring and/or name of the function:

def divide(a, b):
    """Divide a by b.  Raises an exception if a and b are not divisible."""
    return a / b

def safe_divide(a, b):
    """Divide a by b.  Returns zero if a and b are not divisible for any reason."""
    try:
        return a / b
    except:
        return 0

As a general rule, a bare except is bad practice and you should instead catch specific exceptions. For example, this code:

try:
   result = x / y
except Exception:
   print("You entered 0 in for denominator")

is incorrect because there are failure modes other than y being zero. Better exception handling might look like this:

try:
    result = x / y
except ZeroDivisionError:
    print("You entered 0 in for denominator")
except TypeError:
    print("One of these things is not a number")

If an exception is raised that you completely didn't expect, it's better to not catch it so that it will cause your program to fail hard and fast; this makes it easier for you to find your bug and fix it.

\$\endgroup\$
9
  • \$\begingroup\$ Don't answer off-topic questions. \$\endgroup\$ – Peilonrayz Feb 6 '20 at 20:26
  • \$\begingroup\$ This question doesn't look off-topic to me, but I respect your opinion. \$\endgroup\$ – Samwise Feb 6 '20 at 20:28
  • \$\begingroup\$ Then you clearly don't know the rules. \$\endgroup\$ – Peilonrayz Feb 6 '20 at 20:30
  • \$\begingroup\$ It ticks all the boxes from codereview.stackexchange.com/help/on-topic, at least with a charitable reading (and why be uncharitable?). If it's in violation of other rules, then yes, I don't know those rules. \$\endgroup\$ – Samwise Feb 6 '20 at 20:32
  • \$\begingroup\$ @SamStafford I think it fails the question about hypothetical code: "Is it actual code from a project rather than pseudo-code or hypothetical code?" \$\endgroup\$ – Benjamin Feb 6 '20 at 20:36

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