From 6124b92251332f5473967100044070affe733f85 Mon Sep 17 00:00:00 2001 From: gadorlhiac Date: Wed, 27 Mar 2024 14:11:47 -0700 Subject: [PATCH] BUG Handle additional errors that can come from unpickling --- lute/execution/ipc.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lute/execution/ipc.py b/lute/execution/ipc.py index e81bd5ec..f1bcc7a2 100644 --- a/lute/execution/ipc.py +++ b/lute/execution/ipc.py @@ -174,7 +174,7 @@ def read(self, proc: subprocess.Popen) -> Message: if self._use_pickle: try: contents = pickle.loads(raw_contents) - except pickle.UnpicklingError as err: + except (pickle.UnpicklingError, ValueError, EOFError) as err: logger.debug("PipeCommunicator (Executor) - Set _use_pickle=False") self._use_pickle = False contents = self._safe_unpickle_decode(raw_contents) @@ -237,9 +237,18 @@ def _safe_unpickle_decode(self, maybe_mixed: bytes) -> Optional[str]: repickled: bytes = pickle.dumps(contents) if len(repickled) < len(maybe_mixed): # Successful unpickling, but pickle stops even if there are more bytes - additional_data: str = maybe_mixed[len(repickled) :].decode() - contents = f"{contents}{additional_data}" - except pickle.UnpicklingError as err: + try: + additional_data: str = maybe_mixed[len(repickled) :].decode() + contents = f"{contents}{additional_data}" + except UnicodeDecodeError: + # Can't decode the bytes left by pickle, so they are lost + missing_bytes: int = len(maybe_mixed) - len(repickled) + logger.debug( + f"PipeCommunicator has truncated message. Unable to retrieve {missing_bytes} bytes." + ) + except (pickle.UnpicklingError, ValueError, EOFError) as err: + # Pickle may also throw a ValueError, e.g. this bytes: b"Found! \n" + # Pickle may also throw an EOFError, eg. this bytes: b"F0\n" try: contents = maybe_mixed.decode() except UnicodeDecodeError as err2: @@ -251,11 +260,6 @@ def _safe_unpickle_decode(self, maybe_mixed: bytes) -> Optional[str]: f"PipeCommunicator unable to decode/parse data! {err3}" ) contents = None - except UnicodeDecodeError as err3: - missing_bytes: int = len(maybe_mixed) - len(repickled) - logger.debug( - f"PipeCommunicator has truncated message. Unable to retrieve {missing_bytes} bytes." - ) return contents def write(self, msg: Message) -> None: