Re-raising the right exception

Discussion in 'Python' started by SM, Oct 21, 2004.

  1. SM

    SM Guest

    try:
    x = 1/0
    except ZeroDivisionError:
    print "caught ZeroDivisionError"
    try:
    name_error
    except NameError:
    print "caught NameError"
    raise

    According to the Python Language Reference
    http://docs.python.org/ref/raise.html
    'raise' re-raises the last expression that was active in the current
    scope. Here apparently "scope" means some sort of lexical scope,
    because this program terminates with a NameError exception and not a
    ZeroDivisionError.

    It seems useful to have a way to raise the exception that is currently
    being handled (ZeroDivisionError in this case) and not any exception
    that happened to be caught earlier in the current exception handler.
    For example,

    try:
    network.command()
    except:
    try:
    network.close()
    except:
    pass
    raise

    I want to make a network call, and if it raises an exception, I want
    to close the network connection before allowing the exception to
    propagate up the stack. However, trying to close the network
    connection might itself raise an exception, and I don't care about
    that exception; I want to send the original exception. Apparently the
    way to do this is:

    try:
    network.command()
    except Exception, bob:
    try:
    network.close()
    except:
    pass
    raise bob
     
    SM, Oct 21, 2004
    #1
    1. Advertising

  2. SM

    Duncan Booth Guest

    SM wrote:

    > For example,
    >
    > try:
    > network.command()
    > except:
    > try:
    > network.close()
    > except:
    > pass
    > raise
    >
    > I want to make a network call, and if it raises an exception, I want
    > to close the network connection before allowing the exception to
    > propagate up the stack. However, trying to close the network
    > connection might itself raise an exception, and I don't care about
    > that exception; I want to send the original exception. Apparently the
    > way to do this is:
    >


    <snip>

    You could move the cleanup code out to another scope:

    try:
    network.command()
    except:
    def network_cleanup():
    try:
    network.close()
    except:
    pass

    network_cleanup()
    raise

    In practice something like network_cleanup probably wants to be called from
    more than one place so it could be in a function defined elsewhere.

    Another option is to use try..finally:

    try:
    network.command()
    finally:
    try:
    network.close()
    except:
    pass

    then you don't need to reraise the exception at all.

    Use the first suggestion if the cleanup only needs to be done when the code
    failed (e.g. to remove partially created files from disc). Use the second
    if the cleanup needs to be done always, e.g. closing files or network
    connections.
     
    Duncan Booth, Oct 21, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Guetttler
    Replies:
    1
    Views:
    583
    Thomas Guetttler
    Sep 10, 2003
  2. Calvin Spealman

    Ideas for yielding and exception raising

    Calvin Spealman, Jun 5, 2004, in forum: Python
    Replies:
    3
    Views:
    317
    Peter Hansen
    Jun 8, 2004
  3. Antoon Pardon
    Replies:
    0
    Views:
    347
    Antoon Pardon
    Mar 15, 2005
  4. leo
    Replies:
    8
    Views:
    388
    Tom Anderson
    Oct 5, 2005
  5. Michael Goerz

    Raising exception on STDIN read

    Michael Goerz, Feb 27, 2008, in forum: Python
    Replies:
    14
    Views:
    604
    Ian Clark
    Feb 29, 2008
Loading...

Share This Page