I have an application that looks like this:
while True:
try:
self.try_to_read_usb_device()
break
except:
time.sleep(1)
I also have an SIGALRM
handler which is supposed to exit the program in case it got stuck somewhere:
def alarm_signal_handler(signal, frame):
# Something went wrong
exit(1)
However the exit(1)
just get caught by the try/except and gets discarded as this is what that specific except
does.
This is quite unexpected to me.
In the complete application there will be a lot of try/except and I don't see myself adding
except SystemExit:
exit(1)
or something for all of them.
Any idea how I should handle that use-case?
You can use os._exit
instead of sys.exit
.
Note that this has obvious drawbacks exactly because it won't go through an exception:
Exit the process with status n, without calling cleanup handlers, flushing stdio buffers, etc.
I'd recommend to instead change your exception handling to catch only things inheriting from Exception
, because SystemExit
doesn't inherit from Exception
for precisely this reason, so it won't be caught accidentally:
except Exception:
See also the SystemExit
documentation:
This exception is raised by the
sys.exit()
function. It inherits fromBaseException
instead ofException
so that it is not accidentally caught by code that catchesException
. This allows the exception to properly propagate up and cause the interpreter to exit.
This also applies to KeyboardInterrupt
by the way - Ctrl+C will be caught by except:
but not by except Exception:
.
It's illustrated pretty well in the exception hierarchy diagram in the Python docs, which you can find here.