Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we adjust which exception is raised for usb.core.USBError in usbtmc.py? #353

Open
dougthor42 opened this issue Feb 10, 2023 · 3 comments

Comments

@dougthor42
Copy link
Contributor

Attempting to open a resource to a USB devices that is already in use results in an Exception. This is difficult for callers to handle, as the raised error is too broad.

Can a different exception be raised here?

raise Exception("failed to set configuration\n %s" % e)

Perhaps a new USBTMCError similar to what is done in VXI11?

class Vxi11Error(Exception):
pass

I'd be happy to implement it if you're OK with the suggestion.

To Reproduce

Steps to reproduce the behavior:

  1. Create your resource manager with the pyvisa-py backend: rm = pyvisa.ResourceManager("@py")
  2. Open a connection to a USB device, eg: instr = rm.open_resource("USB:: ... ::INSTR")
  3. Open another connection: instr = rm.open_resource("USB:: ... ::INSTR")
  4. See error
>>> import pyvisa
>>> rm = pyvisa.ResourceManager("@py")
>>> instr = rm.open_resource("USB0::2391::1287::MY56510237::0::INSTR")
>>> instr = rm.open_resource("USB0::2391::1287::MY56510237::0::INSTR")
Traceback (most recent call last):
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/protocols/usbtmc.py", line 216, in __init__
    self.usb_dev.set_configuration()
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/usb/core.py", line 869, in set_configuration
    self._ctx.managed_set_configuration(self, configuration)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/usb/core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/usb/core.py", line 148, in managed_set_configuration
    self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/usb/backend/libusb1.py", line 794, in set_configuration
    _check(self.lib.libusb_set_configuration(dev_handle.handle, config_value))
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/usb/backend/libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 16] Resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa/highlevel.py", line 3284, in open_resource
    res.open(access_mode, open_timeout)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa/resources/resource.py", line 282, in open
    self.session, status = self._resource_manager.open_bare_resource(
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa/highlevel.py", line 3209, in open_bare_resource
    return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/highlevel.py", line 167, in open
    sess = cls(session, resource_name, parsed, open_timeout)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/sessions.py", line 325, in __init__
    self.after_parsing()
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/usb.py", line 81, in after_parsing
    self.interface = self._intf_cls(
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/protocols/usbtmc.py", line 303, in __init__
    super(USBTMC, self).__init__(vendor, product, serial_number, **kwargs)
  File "/usr/local/google/home/dthor/.virtualenvs/pyle/lib/python3.9/site-packages/pyvisa_py/protocols/usbtmc.py", line 218, in __init__
    raise Exception("failed to set configuration\n %s" % e)
Exception: failed to set configuration
 [Errno 16] Resource busy

Output of pyvisa-info

$ pyvisa-info
Machine Details:
   Platform ID:    Linux-5.19.11-1rodete1-amd64-x86_64-with-glibc2.36
   Processor:      

Python:
   Implementation: CPython
   Executable:     /usr/local/google/home/dthor/.virtualenvs/pyle/bin/python3
   Version:        3.9.13
   Compiler:       GCC 10.2.1 20210110
   Bits:           64bit
   Build:          Jun  8 2022 22:16:58 (#main)
   Unicode:        UCS4

PyVISA Version: 1.13.0

Backends:
   ivi:
      Version: 1.13.0 (bundled with PyVISA)
      Binary library: Not found
   py:
      Version: 0.6.0
      ASRL INSTR: Available via PySerial (3.5)
      USB INSTR: Available via PyUSB (1.0.2). Backend: libusb1
      USB RAW: Available via PyUSB (1.0.2). Backend: libusb1
      TCPIP INSTR: Available 
      VICP INSTR: Available 
      TCPIP SOCKET: Available 
      GPIB INSTR:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of funcionality.
         No module named 'gpib'
   sim:
      Version: 0.5.1
      Spec version: 1.1
@dougthor42
Copy link
Contributor Author

It looks like this applies to tcpip.py in a couple places too:

raise Exception("error creating link: %d" % error)

raise Exception("could not connect: {0}".format(str(ret_status)))

raise Exception("could not connect: {0}".format(str(e)))

These could be TCPIPError or similar.

@MatthieuDartiailh
Copy link
Member

Technically those errors should never bubble up to the users. They should be converted to proper return code before getting out of pyvisa-py so typically here https://github.com/pyvisa/pyvisa-py/blob/main/pyvisa_py/highlevel.py#L167

Since they may have fairly different origins for different hardware connection, it may make sense to have a generic exception class providing a method to get a return code for VISA and some logging facility (since we are losing information when converting teh exception to an int). Then each hardware could deal with generating the error based on what may go wrong for this specific hardware.

Would you be interested in working on such a solution ?

@dougthor42
Copy link
Contributor Author

Sure I'll take a stab at it. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants