From 3ce750d3cc7ef51b9caef2c582d00b79074cc886 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 21:01:56 +0200 Subject: [PATCH 1/3] [OMCSessionException] add exception handling for OMCSession* --- OMPython/OMCSession.py | 4 ++++ OMPython/__init__.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 63fbba00c..0f38023e7 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -75,6 +75,10 @@ def wait(self, timeout): return self.process.wait(timeout=timeout) +class OMCSessionException(Exception): + pass + + class OMCSessionBase(metaclass=abc.ABCMeta): def __init__(self, readonly=False): diff --git a/OMPython/__init__.py b/OMPython/__init__.py index 29eaca991..eee36acc9 100644 --- a/OMPython/__init__.py +++ b/OMPython/__init__.py @@ -36,7 +36,7 @@ CONDITIONS OF OSMC-PL. """ -from OMPython.OMCSession import OMCSessionBase, OMCSessionZMQ +from OMPython.OMCSession import OMCSessionBase, OMCSessionZMQ, OMCSessionException from OMPython.ModelicaSystem import ModelicaSystem, ModelicaSystemError, LinearizationResult # global names imported if import 'from OMPython import *' is used @@ -45,6 +45,7 @@ 'ModelicaSystemError', 'LinearizationResult', + 'OMCSessionException', 'OMCSessionZMQ', 'OMCSessionBase', ] From e1f01b55e0f5ce53fc4567b6e9cbf263b6974a48 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 21:21:31 +0200 Subject: [PATCH 2/3] [OMCSessionZMQ] use specific exceptions instead of generic Exception where possible --- OMPython/OMCSession.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 0f38023e7..e51b5fe7a 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -373,9 +373,10 @@ def __del__(self): self._omc_log_file.close() try: self._omc_process.wait(timeout=2.0) - except Exception: + except subprocess.TimeoutExpired: if self._omc_process: - logger.warning("OMC did not exit after being sent the quit() command; killing the process with pid=%s", self._omc_process.pid) + logger.warning("OMC did not exit after being sent the quit() command; " + "killing the process with pid=%s", self._omc_process.pid) self._omc_process.kill() self._omc_process.wait() @@ -405,14 +406,14 @@ def _start_omc_process(self, timeout): try: with open(self._dockerCidFile, "r") as fin: self._dockerCid = fin.read().strip() - except Exception: + except IOError: pass if self._dockerCid: break time.sleep(timeout / 40.0) try: os.remove(self._dockerCidFile) - except Exception: + except FileNotFoundError: pass if self._dockerCid is None: logger.error("Docker did not start. Log-file says:\n%s" % (open(self._omc_log_file.name).read())) @@ -520,9 +521,10 @@ def _connect_to_omc(self, timeout): while True: if self._dockerCid: try: - self._port = subprocess.check_output(["docker", "exec", self._dockerCid, "cat", self._port_file], stderr=subprocess.DEVNULL).decode().strip() + self._port = subprocess.check_output(["docker", "exec", self._dockerCid, "cat", self._port_file], + stderr=subprocess.DEVNULL).decode().strip() break - except Exception: + except subprocess.CalledProcessError: pass else: if os.path.isfile(self._port_file): From 7a61ae76ab1f74e9afcdcedc83df722d81afd8bf Mon Sep 17 00:00:00 2001 From: syntron Date: Fri, 25 Apr 2025 22:01:22 +0200 Subject: [PATCH 3/3] [OMCSessionBase] use OMCSessionException instead of generic Exception --- OMPython/OMCSession.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index e51b5fe7a..8883ffa12 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -126,7 +126,7 @@ def ask(self, question, opt=None, parsed=True): try: res = self.sendExpression(expression, parsed=parsed) - except Exception: + except OMCSessionException: logger.error("OMC failed: %s, %s, parsed=%s", question, opt, parsed) raise @@ -368,7 +368,7 @@ def __init__(self, readonly=False, timeout=10.00, def __del__(self): try: self.sendExpression("quit()") - except Exception: + except OMCSessionException: pass self._omc_log_file.close() try: @@ -417,7 +417,8 @@ def _start_omc_process(self, timeout): pass if self._dockerCid is None: logger.error("Docker did not start. Log-file says:\n%s" % (open(self._omc_log_file.name).read())) - raise Exception("Docker did not start (timeout=%f might be too short especially if you did not docker pull the image before this command)." % timeout) + raise OMCSessionException("Docker did not start (timeout=%f might be too short especially if you did " + "not docker pull the image before this command)." % timeout) dockerTop = None if self._docker or self._dockerContainer: @@ -434,17 +435,16 @@ def _start_omc_process(self, timeout): try: self._omc_process = DummyPopen(int(columns[1])) except psutil.NoSuchProcess: - raise Exception( - f"Could not find PID {dockerTop} - is this a docker instance spawned without --pid=host?\n" - f"Log-file says:\n{open(self._omc_log_file.name).read()}") + raise OMCSessionException( + f"Could not find PID {dockerTop} - is this a docker instance spawned " + f"without --pid=host?\nLog-file says:\n{open(self._omc_log_file.name).read()}") break if self._omc_process is not None: break time.sleep(timeout / 40.0) if self._omc_process is None: - - raise Exception("Docker top did not contain omc process %s:\n%s\nLog-file says:\n%s" - % (self._random_string, dockerTop, open(self._omc_log_file.name).read())) + raise OMCSessionException("Docker top did not contain omc process %s:\n%s\nLog-file says:\n%s" + % (self._random_string, dockerTop, open(self._omc_log_file.name).read())) return self._omc_process def _getuid(self): @@ -465,7 +465,9 @@ def _set_omc_command(self, omc_path_and_args_list): if (self._docker or self._dockerContainer) and sys.platform == "win32": extraFlags = ["-d=zmqDangerousAcceptConnectionsFromAnywhere"] if not self._interactivePort: - raise Exception("docker on Windows requires knowing which port to connect to. For dockerContainer=..., the container needs to have already manually exposed this port when it was started (-p 127.0.0.1:n:n) or you get an error later.") + raise OMCSessionException("docker on Windows requires knowing which port to connect to. For " + "dockerContainer=..., the container needs to have already manually exposed " + "this port when it was started (-p 127.0.0.1:n:n) or you get an error later.") else: extraFlags = [] if self._docker: @@ -478,7 +480,7 @@ def _set_omc_command(self, omc_path_and_args_list): dockerNetworkStr = [] extraFlags = ["-d=zmqDangerousAcceptConnectionsFromAnywhere"] else: - raise Exception('dockerNetwork was set to %s, but only \"host\" or \"separate\" is allowed') + raise OMCSessionException('dockerNetwork was set to %s, but only \"host\" or \"separate\" is allowed') self._dockerCidFile = self._omc_log_file.name + ".docker.cid" omcCommand = ["docker", "run", "--cidfile", self._dockerCidFile, "--rm", "--env", "USER=%s" % self._currentUser, "--user", str(self._getuid())] + self._dockerExtraArgs + dockerNetworkStr + [self._docker, self._dockerOpenModelicaPath] elif self._dockerContainer: @@ -508,7 +510,7 @@ def _get_omhome(self, omhome: str = None): if path_to_omc is not None: return pathlib.Path(path_to_omc).parents[1] - raise ValueError("Cannot find OpenModelica executable, please install from openmodelica.org") + raise OMCSessionException("Cannot find OpenModelica executable, please install from openmodelica.org") def _get_omc_path(self) -> pathlib.Path: return self.omhome / "bin" / "omc" @@ -539,7 +541,8 @@ def _connect_to_omc(self, timeout): name = self._omc_log_file.name self._omc_log_file.close() logger.error("OMC Server did not start. Please start it! Log-file says:\n%s" % open(name).read()) - raise Exception(f"OMC Server did not start (timeout={timeout}). Could not open file {self._port_file}") + raise OMCSessionException(f"OMC Server did not start (timeout={timeout}). " + "Could not open file {self._port_file}") time.sleep(timeout / 80.0) self._port = self._port.replace("0.0.0.0", self._serverIPAddress) @@ -555,7 +558,7 @@ def _connect_to_omc(self, timeout): def sendExpression(self, command, parsed=True): p = self._omc_process.poll() # check if process is running if p is not None: - raise Exception("Process Exited, No connection with OMC. Create a new instance of OMCSessionZMQ") + raise OMCSessionException("Process Exited, No connection with OMC. Create a new instance of OMCSessionZMQ!") attempts = 0 while True: @@ -569,7 +572,7 @@ def sendExpression(self, command, parsed=True): self._omc_log_file.seek(0) log = self._omc_log_file.read() self._omc_log_file.close() - raise Exception(f"No connection with OMC (timeout={self._timeout}). Log-file says: \n{log}") + raise OMCSessionException(f"No connection with OMC (timeout={self._timeout}). Log-file says: \n{log}") time.sleep(self._timeout / 50.0) if command == "quit()": self._omc.close()