Try:
#some statement
Try:
#some statement
Except:
#statement1
Raise exception()
#statement2
Except: #some statement
Can I pass the control like the above code in python., will the inner except pass the control to the outer except and will the #statement2 be executed?
This code will answer your question:
#!/usr/bin/env python
import sys
try:
try:
raise Exception("first exception")
except Exception as e:
print e.message
raise Exception("second exception")
print "second statement" # never printed - 'dead code'
except Exception as e:
print e.message
Both except blocks are executed but the statement after raising the second exception is not.
Generally you should know that once an exception is raised, nothing executes until it is caught by an except block that is relevant to this exception or any superclass of it.
Related
Let's say I have a code that looks like this:
try:
raise ValueError()
except ValueError as err:
print("ValueError block")
raise
except Exception as err:
print("Exception block")
This prints:
ValueError block
and raises an exception. I want it to just print:
ValueError block
Exception block
Can I achieve that by somehow calling the Exception block from the ValueError block?
You have to obey the rules of exception handling. In this case, you can use a nested try block:
try:
try:
raise ValueError()
except ValueError as err:
print("ValueError block")
raise
except Exception as err:
print("Exception block")
Since ValueError is a subclass of Exception, you could write one except block and check with isinstance:
try:
raise ValueError()
except Exception as err:
if isinstance(err, ValueError):
print("ValueError block")
print("Exception block")
I have specified specific exception in different except block, but when I raise exchangelib.errors.ErrorFolderNotFound it goes to wrong except block (i.e it goes to TransportError except block.
I have this code :
import exchangelib
try:
#some code
raise exchangelib.errors.ErrorFolderNotFound
except exchangelib.errors.TransportError:
print("transport error caught")
except exchangelib.errors.ErrorFolderNotFound:
print("folder not found caught")
except Exception as e:
print("exception caught")
but when I move the ErrorFolderNotFound except block above the TransportError block it goes to the right block (i.e ErrorFolderNotFound except block)
import exchangelib
try:
#some code
raise exchangelib.errors.ErrorFolderNotFound
except exchangelib.errors.ErrorFolderNotFound:
print("folder not found caught")
except exchangelib.errors.TransportError:
print("transport error caught")
except Exception as e:
print("exception caught")
Why is this behavior occurring ,as I am giving specific exception in the except block ?.
Also if any other exception occurs which belong to the same family of exchangelib, it goes to except block which already has some specific exchangelib error defined in the except block, it should go to `except block of Exception
Here in below code , when error is raised ,it goes to TransportError except block, but logically it should go to Exception except block
import exchangelib
try:
#some code
raise exchangelib.errors.ErrorFolderNotFound
except exchangelib.errors.TransportError:
print("transport error caught")
except Exception as e:
print("exception caught")
Without knowing the hierarchy of the Exceptions in exchangelib.errors, I can only guess that ErrorFolderNotFound inherits from TransportError. I.e.,
class MyBaseError(BaseException):
pass
class TransportError(MyBaseError):
pass
class ErrorFolderNotFound(TransportError):
pass
try:
#some code
raise ErrorFolderNotFound
except TransportError:
print("transport error caught")
except ErrorFolderNotFound:
print("folder not found caught")
except Exception as e:
print("exception caught")
which will print out transport error caught
If we change the hierarchy so that ErrorFolderNotFound does not inherit from TransportError. I.e.,
class MyBaseError(BaseException):
pass
class TransportError(MyBaseError):
pass
class ErrorFolderNotFound(MyBaseError):
pass
try:
#some code
raise ErrorFolderNotFound
except TransportError:
print("transport error caught")
except ErrorFolderNotFound:
print("folder not found caught")
except Exception as e:
print("exception caught")
then we'll get folder not found caught
I'm trying to exit a script from inside a try: except: block except it just goes on to the exception case.
None of these...
try:
exit()
except:
pass()
try:
quit()
except:
pass
import sys
try:
sys.exit()
except:
pass
...exit my script, they just go on to the except case.
How would I exit my script from inside one of these blocks?
All of these examples raise the SystemExit exception and you are catching that exception, a blank except clause will catch all exceptions.
This is the reason why you should always specify the exception you intend to catch or at least use except Exception eg
try:
exit()
except Exception:
pass
try:
quit()
except Exception:
pass
import sys
try:
sys.exit()
except Exception:
pass
With that change in place, all of you examples will cause your Python app to exit
I have a script that catches all exceptions, which works great unless I want to abort the script manually (with control + c). In this case the abort command appears to be caught by the exception instead of quitting.
Is there a way to exclude this type of error from the exception? For example something as follows:
try:
do_thing()
except UserAbort:
break
except Exception as e:
print(e)
continue
You could just force to exit the program whenever the exception happens:
import sys
# ...
try:
do_thing()
except UserAbort:
break
except KeyboardInterrupt:
sys.exit()
pass
except Exception as e:
print(e)
continue
try:
raise KeyError()
except KeyError:
print "Caught KeyError"
raise Exception()
except Exception:
print "Caught Exception"
As expected, raising Exception() on the 5th line isn't caught in the final except Exception clause. In order the catch the exception inside of the except KeyError block, I have to add another try...except like this and duplicate the final except Exception logic:
try:
raise KeyError()
except KeyError:
print "Caught KeyError"
try:
raise Exception()
except Exception:
print "Caught Exception"
except Exception:
print "Caught Exception"
In Python, is it possible to pass the flow of execution to the final except Exception block like I am trying to do? If not, are there strategies for reducing the duplication of logic?
You could add another level of try nesting:
try:
try:
raise KeyError()
except KeyError:
print "Caught KeyError"
raise Exception()
except Exception:
print "Caught Exception"