Search code examples
pythonpython-3.xpandastry-catch

How to suppress irrelevant errors in a try block


Suppose I want to check that a certain entry is in a Series. I would like to try to access that entry, and if that fails, raise a simple, short ValueError.

For example, I have a series that doesn't have entry C - I want a check to halt the script. Example:

s = {'A': 1, 'B': 2}
s = pd.Series(s)

try:
    s['C']
except:
    raise ValueError('C is missing.')

But this code throws a long KeyError before spitting out the ValueError. It works, but is verbose.

(I know that I can use an assert statement instaead.)

Why doesn't the try block suppress the KeyError - isn't that part of its purpose? Is there a way to get my intended behavior?


Solution

  • You are seeing exception chaining. This extra information can be suppressed with a from None clause in your raise statement. Consider this (totally contrived) case where I am suppressing a ZeroDivisionError and raising a KeyError:

    >>> try:
    ...     1/0
    ... except ZeroDivisionError:
    ...     raise KeyError
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    ZeroDivisionError: division by zero
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    KeyError
    

    But if I use from none:

    >>> try:
    ...     1/0
    ... except ZeroDivisionError:
    ...     raise KeyError from None
    ...
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    KeyError
    >>>
    

    Also note, you really should not use a bare except clause. Catch as specific an error as possible.