-1

At below, I have a try-except block that I want to refactor it. As you see, it is not pythonic and not-maintainable.

 try:
     try:
         foo()
     except xError:
         doSth()
         raise
 except:
     exc_type = sys.exc_info()[0]
     if exc_type == FooError:
         doBlaBla()
     else:   
         doFlaFla() 

     blablabla()       # whatever the exceptions is, run this code block
     foobar()
     zoo()
     ...        

I change that block as the below code;

 try:
     try:
         foo()
     except xError:
         doSth()
         raise
 except FooError:
     doBlaBla()
     raise
 except:
     doFlaFla() 
     raise

     blablabla()       # This is where the problem happens for me.
     foobar()
     zoo()
     ...        

As you can see, I need a except-finally like operation. It will not run when no exception raises but any exceptions. What do you advice ? How should I change this clode block ?

myildirim
  • 2,248
  • 2
  • 19
  • 25

3 Answers3

0

Why you've used innder try exempt block? In my opinion, it is a good practice to put finally except statement, that will catch unexpected error.

So I suggest:

try:
    fn()
except Exception1:
    do stuff you want
except Exception 2:
    do another stuff
except Exception as e:
    # Here you will catch an unexpected error, and you can log it
    raise UnknownError -> do stuff you want
Nodari Lipartiya
  • 1,148
  • 3
  • 14
  • 24
0

You can wrap your exception-code in a try-finally block, for example:

try:
    try:
        foo()
    except xError:
        doSth()
        raise
# catch Exception to avoid catching system errors
except Exception as e:
    try:
        if isinstance(e, FooError):
            doBlaBla()
        else:   
            doFlaFla() 
            raise
    finally:
        # this will always run regardless of what you raise

Another approach could be something like this:

e = None
try:
    try:
        foo()
    except xError:
        doSth()
        raise
except FooError as e:
    doBlaBla()
except Exception as e:
    doFlaFla() 
    raise
finally:
    # this will always run regardless of what you raise
    if e:
        # exception took place...
sirfz
  • 4,097
  • 23
  • 37
  • As far as i escape from the nested-try blocks, but it seems, it could work. – myildirim Sep 03 '14 at 11:49
  • If you want to split the `except` blocks then your best bet is to put the "common" code in a function and call it in each `except` block. – sirfz Sep 03 '14 at 11:51
  • I am already aware of it,but, actual code base is much larger and not-seperatable. Anyway, thanks for answer. – myildirim Sep 03 '14 at 11:58
  • Perhaps the other approach in my edited answer is more what you're looking for? – sirfz Sep 03 '14 at 12:12
  • No, unfortunately. Because, your "except Exception as e:" statement overrides my custom exceptions and causes to lose the main reason of the error.So, I can just see the generic Exception. – myildirim Sep 03 '14 at 12:30
  • `Exception` is just the superclass of exceptions in Python, your custom exception's type isn't changed if that's your concern – sirfz Sep 03 '14 at 12:34
  • Ahh, I checked it, you are right. I thought that it overrides the original error but it doesn't! Thanks. – myildirim Sep 03 '14 at 12:40
  • But, there is another problem here, please check this out: http://stackoverflow.com/questions/18982610/difference-between-except-and-except-exception-as-e-in-python – myildirim Sep 03 '14 at 12:46
  • It's not really an issue. In general, you should only worry about catching non-system-exiting exceptions and not system errors (like `KeyboardInterrupt` and other uncontrollable errors). – sirfz Sep 03 '14 at 12:58
0

Why not something like:

def others():
    """Other stuff to do when non-xError occurs.""" 
    blablabla()
    foobar()
    zoo()

and then factor into a single try:

try:
    foo()
except xError:
    doSth()
    raise
except FooError:
    doBlaBla()
    others()
except Exception:
    doFlaFla()
    others()

A bare except is usually a bad idea.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Because it is not as easy as this. The 'others' code block has many dependencies, so it can not be seperated. – myildirim Sep 03 '14 at 12:53
  • What "dependencies"? Can you refactor to remove them (e.g. using explicit parameters and `return` values)? In a more general sense, how on earth do you expect anyone to help you refactor your code when you don't provide enough information on what you already have? – jonrsharpe Sep 03 '14 at 12:56