From db8f22bb208c57f2b03f71096e42d884c371c009 Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Tue, 17 Sep 2024 19:13:24 +0200 Subject: [PATCH] sessions: improve handling of open connection error for TCPIP resources --- pyvisa_py/__init__.py | 3 +++ pyvisa_py/highlevel.py | 5 +++- pyvisa_py/sessions.py | 7 ++++++ pyvisa_py/tcpip.py | 55 ++++++++++++++++++++++++++++-------------- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/pyvisa_py/__init__.py b/pyvisa_py/__init__.py index a625616..4b5576f 100644 --- a/pyvisa_py/__init__.py +++ b/pyvisa_py/__init__.py @@ -7,8 +7,11 @@ """ +import logging import sys +LOGGER = logging.getLogger("pyvisa.pyvisa-py") + if sys.version_info >= (3, 8): from importlib.metadata import PackageNotFoundError, version else: diff --git a/pyvisa_py/highlevel.py b/pyvisa_py/highlevel.py index 4d0258c..96a0ecc 100644 --- a/pyvisa_py/highlevel.py +++ b/pyvisa_py/highlevel.py @@ -165,7 +165,10 @@ def open( parsed.interface_type_const, parsed.resource_class ) - sess = cls(session, resource_name, parsed, open_timeout) + try: + sess = cls(session, resource_name, parsed, open_timeout) + except sessions.OpenError as e: + return 0, e.error_code return self._register(sess), StatusCode.success diff --git a/pyvisa_py/sessions.py b/pyvisa_py/sessions.py index 6693949..d12e47b 100644 --- a/pyvisa_py/sessions.py +++ b/pyvisa_py/sessions.py @@ -32,6 +32,13 @@ T = TypeVar("T", bound=Type["Session"]) +class OpenError(Exception): + """Custom exception signaling we failed to open a resource.""" + + def __init__(self, error_code: int = StatusCode.error_resource_not_found): + self.error_code = error_code + + class UnknownAttribute(Exception): """Custom exception signaling a VISA attribute is not supported.""" diff --git a/pyvisa_py/tcpip.py b/pyvisa_py/tcpip.py index 4d09a7a..0f249f6 100644 --- a/pyvisa_py/tcpip.py +++ b/pyvisa_py/tcpip.py @@ -18,9 +18,10 @@ from pyvisa import attributes, constants, errors, rname from pyvisa.constants import BufferOperation, ResourceAttribute, StatusCode -from . import common +from . import common, LOGGER from .protocols import hislip, rpc, vxi11 -from .sessions import Session, UnknownAttribute, VISARMSession +from .sessions import OpenError, Session, UnknownAttribute, VISARMSession + # Let psutil be optional dependency try: @@ -135,17 +136,25 @@ def after_parsing(self) -> None: else: sub_address = self.parsed.lan_device_name port = 4880 - self.interface = hislip.Instrument( - self.parsed.host_address, - open_timeout=( - self.open_timeout * 1000.0 - if self.open_timeout is not None - else self.open_timeout - ), - timeout=self.timeout, - port=port, - sub_address=sub_address, - ) + + try: + self.interface = hislip.Instrument( + self.parsed.host_address, + open_timeout=( + self.open_timeout * 1000.0 + if self.open_timeout is not None + else self.open_timeout + ), + timeout=self.timeout, + port=port, + sub_address=sub_address, + ) + except OSError as e: + LOGGER.exception( + f"Failed to open HiSLIP connection to {self.parsed.host_address} " + f"on port {port} with lan device name {sub_address}" + ) + raise OpenError() from e # initialize the constant attributes self.attrs[ResourceAttribute.dma_allow_enabled] = constants.VI_FALSE @@ -482,7 +491,10 @@ def after_parsing(self) -> None: try: self.interface = Vxi11CoreClient(host_address, port, self.open_timeout) except rpc.RPCError: - raise errors.VisaIOError(constants.VI_ERROR_RSRC_NFOUND) + LOGGER.exception( + f"Failed to open VX11 connection to {host_address} on port {port}" + ) + raise OpenError() # vxi11 expect all timeouts to be expressed in ms and should be integers self.lock_timeout = 10000 @@ -511,7 +523,7 @@ def close(self) -> StatusCode: try: self.interface.destroy_link(self.link) except (errors.VisaIOError, socket.error, rpc.RPCError) as e: - print("Error closing VISA link: {}".format(e)) + LOGGER.error("Error closing VISA link: {}".format(e)) self.interface.close() self.link = 0 @@ -870,9 +882,16 @@ def after_parsing(self) -> None: else: port = 1861 - self.interface = pyvicp.Client( - self.parsed.host_address, port, timeout=self.timeout - ) + try: + self.interface = pyvicp.Client( + self.parsed.host_address, port, timeout=self.timeout + ) + except OSError as e: + LOGGER.exception( + f"Failed to open VICP connection to {self.parsed.host_address} " + f"on port {port}" + ) + raise OpenError() from e # initialize the constant attributes for name in ("SEND_END_EN", "TERMCHAR", "TERMCHAR_EN"):