0

I want to handle different exceptions in such way that there will be common handling for any exception and additional specific handling for subprocess.CalledProcessError. Like this:

try:
    check_output(shlex.split(rsync_cmd))
except CalledProcessException as e:
    # do some stuff
    # do common exception handling
except Exception as e:
    # do the same common handling

I don't want to duplicate code so currently I end up with this code:

try:
    check_output(shlex.split(rsync_cmd))
except Exception as e:
    if isinstance(e, CalledProcessError) and e.returncode == 24:
        # do some stuff
    # do common handling

What's the best practice to run specific code for one exception and to run common code for all exceptions at the same time?

1
  • 1
    But I don't want to run exactly the same code for both Exceptions. I want to handle it in a different way with one common part. It is a different case. Commented Mar 17, 2016 at 9:28

4 Answers 4

3

You could use nested try:...except blocks. I don't think it's a satisfactory solution, but here's a simple example.

for i in (1, 0, 'z'):
    try:
        try:
            print(i, end=' ')
            x = 1 / i
            print(x)
        except TypeError as e:
            print(e)
            raise
        except ZeroDivisionError as e:
            print(e)
            raise
    except (TypeError, ZeroDivisionError) as e:
        print('Common stuff', e)

output

1 1.0
0 float division
Common stuff float division
z unsupported operand type(s) for /: 'int' and 'str'
Common stuff unsupported operand type(s) for /: 'int' and 'str'

Tested on Python 2.6.6, with from __future__ import print_function, division

Sign up to request clarification or add additional context in comments.

Comments

1

You may check error not only against class, but also a tuple of classes. In each branch you may check specific properties.

    try:
           n=0/0
    except (IOError, ImportError) as e:
         print(1)
    except (NameError) as e:
         print(2)

    Traceback (most recent call last):
    File "<input>", line 2, in <module>
         n=0/0
    ZeroDivisionError: division by zero

4 Comments

Thanks, but I want to have a common code for handling both exceptions with additional code for the first one. This is a different case.
What if move to a function common case and call it whenever need?
I already have a function remove_key() to call it in except: block, but I would like to avoid duplicate function calls. I want to know if there is a better solution than checking exception class like I do now.
I do not see any solution which would be much better readable. So-so.
1

Use inheritance in your exceptions.

class GeneralException(Exception)
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class SpecificException(GeneralException)
    def __init__(self, value):
        self.value = value
        super(SpecificException, self).__init__()
    def __str__(self):
        super(SpecificException, self).__str__()
        return repr(self.value)

Base logic is, you trigger SpecificExceptions and they all super call GeneralException to execure related operations

2 Comments

That is really great for custom exceptions, but this is not my case. Wrapping CalledProcessError and Exception in my own classes is a bit overkill.
If you avoid Wrapping, then using simple two-step execption handling is the only solution. try to catch CalledProcessError, otherwise, catch any other exception
1

Create a function that handles the common operations. That's what functions are for.

def common_exception_handling(e):
    # do stuff with e
    return  # possibly something

# ...

try:
    check_output(shlex.split(rsync_cmd))
except CalledProcessException as e:
    # do some stuff
    common_exception_handling(e)
except Exception as e:
    common_exception_handling(e)

4 Comments

I already have a function, but I would like to avoid duplication of code, even if it is a single line (personal taste). Thanks anyway!
Maybe you're right ;) But I'm seeking for a best practice, not for a solution (I already have one).
Functions are a best practice.
@Gevial there is no other "best practice" for this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.