I'm wondering if we can do something like the following:
We catch socket error and if the message is different than some value,
raise the exception forward to be caught on the next general except clause below?
try:
some logic to connect to a server..
except socket.error as se:
if se.messsage != '123':
raise Exception(se.message)
except exception as ex:
log.error('write something')
To do this, you need a set of try-catch blocks. Once, an exception has been caught, re-throwing the exception results in it being caught at the outer level. Try if else inside the blocks or simply nest try-except block in another one like this:
try:
try:
#...
except:
raise
except:
pass
You can simply re-raise the exception with raise without arguments:
try:
# some code
except:
if condition:
raise
Related
I am trying to catch an SQLAlchemy operation result but am unsure if I can do it. Following is the code -
#contextmanager
def transaction_scope(session, close_at_exit=False):
try:
yield session
session.commit()
return True
except Exception:
session.rollback()
return False
finally:
if close_at_exit:
session.close()
with Session() as session:
with transaction_scope(session):
session.add(row)
# Catch if the above insert (add) operation is successful or not
I am inserting a record into the database. I want to get the boolean response from the transaction_scope() if my insert operation is successful or not.
You can always catch, respond to, and rethrow an exception.
with Session() as session:
with transaction_scope(session):
try:
session.add(row)
except Exception as exc:
# Oh no! It failed! Do something here...
raise
Note that the raise keyword, without an exception, can only be used in an except block and re-raises the current exception with its original stack trace intact. So we can respond to the exception and then re-raise it to allow the transaction_scope to roll back the transaction as it's supposed to.
If disconnect is called, I want to restart the main method from the connection.py file. Main method does not restart with existing code when disconnect occurs.
connection.py file*
def disconnect(flags):
#do something
raise RuntimeError('You have been disconnected')
main.py file*
import connection
def main():
while True:
try:
#do something to invoke disconnect
except RuntimeError('You have been disconnected'):
main()
main()
Your try-except block is wrong. I ran your code in python3, and it raised a very clear error, "builtins.TypeError: catching classes that do not inherit from BaseException is not allowed" Because of that unhandled exception, you exit main.
Try these:
try:
raise RuntimeError('You have been disconnected')
except RuntimeError:
print ('caught')
try:
raise RuntimeError('You have been disconnected')
except RuntimeError as e:
print (str(e))
Because you already have a while loop in main, there's no need to recursively call main again. Just let the while loop do its job:
def main():
while True:
connect()
try:
raise RuntimeError('You have been disconnected')
except RuntimeError as e:
print (str(e))
If the error is caught, then you will still be inside the while loop.
While trying to implement a DNSRequest, I also needed to do some exception handling and noticed something weird. The following code is able to catch DNS request timeouts
def lambda_handler(event, context):
hostname = "google.de"
dnsIpAddresses = event['dnsIpAddresses']
dnsResolver = dns.resolver.Resolver()
dnsResolver.lifetime = 1.0
result = {}
for dnsIpAddress in dnsIpAddresses:
dnsResolver.nameservers = [dnsIpAddress]
try:
myAnswers = dnsResolver.query(hostname, "A")
print(myAnswers)
result[dnsIpAddress] = "SUCCESS"
except dns.resolver.Timeout:
print("caught Timeout exception")
result[dnsIpAddress] = "FAILURE"
except dns.exception.DNSException:
print("caught DNSException exception")
result[dnsIpAddress] = "FAILURE"
except:
result[dnsIpAddress] = "FAILURE"
print("caught general exception")
return result
Now, if I removed the Timeout block, and assuming that a Timeout would occur, on a DNSException the message
caught DNSException exception
will never be shown.
Now, if I removed the DNSException block, and assuming that a Timeout would occur, the message
caught general exception
will never be shown.
But the Timeout extends the DNSException and the DNSException extends Exception. I had the expectation that at least the general expect block should work.
What am I missing?
In your last block try making the print line come before result[dnsIpAddress] = "FAILURE"
My guess is either there is more code than what is shown here or the line before the print statement causes a different exception.
I am trying to learn python's signal module. Please consider the example below:
def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None):
import signal
class TimeoutError(Exception):
pass
def handler(signum, frame):
print "Trying to raise exception"
raise TimeoutError
# set the timeout handler
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout_duration)
try:
result = func(*args, **kwargs)
except TimeoutError as exc:
result = default
finally:
signal.alarm(0)
return result
and,
import time
def foo():
for i in range(10):
time.sleep(0.5)
print "Sleeping"
On calling the function timeoutFn(foo) the following gets printed but it does raise the exception.
Shouldn't it raise the TimeoutError? But, all it prints is
Sleeping
Trying to raise exception
and program stops.
The exception has not been raised, because you catch it. Pay attention to the line:
except TimeoutError as exc:
result = default
The block means, that if the exception TimeoutError had been raised, result will be assigned to default (which is None in your example) and the scripts continues further without showing an exception.
Update:
signal.alarm doesn't stop the flow. So the exception will be raised by timeout and if the script will be by that time in a try block, than the exception will be caught. You can see better how does it work if you increase timeout_duration to 3. Than there will be more time to print several 'sleep' messages. It shows, that by the time when the exception is raised, the interpreter had entered the try block.
I have a try/except block that sends a message and waits for confirmation from client. If the client terminates, pickle raises an EOFError, but the code below does not catch the error and execute the graceful shut down. It instead prints stack trace. I assume it has to do with the line "except socket.error, EOFError:" - am I using the wrong syntax to handle both socket.error and EOFError there?
try:
msgs = [1]
self.sock.send(pickle.dumps(msgs))
rdy = pickle.loads(self.sock.recv(2097152))
except socket.error, EOFError:
print 'log socketmanager closing'
self.terminate()
break
In Python 2.x, the form except a, b catches an exception of type a and assign it to a variable called b. In your case this would result in EOFError being ignored. Try this instead:
...
except (socket.error, EOFError):
...
Edit: to elaborate, the new syntax in Python 3.0, and available, though not required, in 2.6+, for capturing the value of an exception is except a as b.
break is causing the error, it can only be used inside a for loop or a try/finally block, not try/except, see docs and more.