From 10d3900c2e88dfb491c9b93b75d47024685f9f66 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Wed, 4 Jan 2023 15:45:00 -0800 Subject: [PATCH] Don't crash if user calls sys.exit() (#434) **Issue:** If user called `sys.exit()` from a WebSocket callback, the program would exit non-gracefully, printing out a big old C stack trace. **Diagnosis:** The websocket callbacks are doing some [extra zealous error checking](https://github.com/awslabs/aws-crt-python/blob/edf0ef624bd84ab6d669b9b8639e2d9a43140c95/source/websocket.c#L246-L250) when calling from C->Python. The Python code is supposed to catch and handle any exceptions resulting from the user's code. C will murder the applications if any other exceptions leak back to C, with the thinking that these must result from bugs in OUR code, so best to just die. Anyway, `sys.exit()` results in a `SystemExit` exception, which inherits from`BaseException` instead of `Exception`, so it was slipping through the Python code's `except Exception:` filter. **Description of changes:** Handle `BaseException` (not just ~Exception~) in the Python section of the callback, so that `SystemExit` doesn't leak back into C and trigger the extra zealous error checker. --- awscrt/websocket.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/awscrt/websocket.py b/awscrt/websocket.py index 0a7c8cc08..e192c0df8 100644 --- a/awscrt/websocket.py +++ b/awscrt/websocket.py @@ -388,7 +388,7 @@ def _on_complete(error_code): try: if on_complete is not None: on_complete(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket.send_frame on_complete callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) self.close() @@ -457,7 +457,7 @@ def _on_connection_setup( # Do not let exceptions from the user's callback bubble up any further. try: self._on_connection_setup_cb(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket on_connection_setup callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) if cbdata.websocket is not None: @@ -472,7 +472,7 @@ def _on_connection_shutdown(self, error_code): try: if self._on_connection_shutdown_cb is not None: self._on_connection_shutdown_cb(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket on_connection_shutdown callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) @@ -485,7 +485,7 @@ def _on_incoming_frame_begin(self, opcode_int, payload_length, fin): try: if self._on_incoming_frame_begin_cb is not None: self._on_incoming_frame_begin_cb(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket on_incoming_frame_begin callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) return False # close websocket @@ -499,7 +499,7 @@ def _on_incoming_frame_payload(self, data): try: if self._on_incoming_frame_payload_cb is not None: self._on_incoming_frame_payload_cb(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket on_incoming_frame_payload callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) return False # close websocket @@ -517,7 +517,7 @@ def _on_incoming_frame_complete(self, error_code): try: if self._on_incoming_frame_complete_cb is not None: self._on_incoming_frame_complete_cb(cbdata) - except Exception: + except BaseException: print("Exception in WebSocket on_incoming_frame_complete callback", file=sys.stderr) sys.excepthook(*sys.exc_info()) return False # close websocket