pyvisa / pyvisa-py

A pure python PyVISA backend
https://pyvisa-py.readthedocs.io
MIT License
288 stars 124 forks source link

How am I supposed to catch a custom exception when I cannot import `pyvisa-py` due to the minus sign in the package name? #146

Open tamasgal opened 6 years ago

tamasgal commented 6 years ago

Dear all,

sometimes I need to deal with exceptions which are raised by pyvisa-py, for example pyvisa-py.protocols.rpc.RPCError. I cannot catch this specific exception, since I need to import it, which is not possible since the package name contains a minus sign (not allowed in Python module/package names).

Maybe I am missing something obvious here, but I have no idea how this package should be used externally.

I could not find anything related in the visa or pyvisa package...

Thanks, Tom

MatthieuDartiailh commented 6 years ago

Hi, First of all, such exceptions should not bubble up to you, so uf you can provide a minimal reproduction script, I will look at fixing the issue. In the meantime you can use importlib to import the module even if its name is invalid in an import statement. That's hiw we import pyvisa-py in the first place.

tamasgal commented 6 years ago

It's hard to reproduce... it happens during very long (>50 hours) data takings from time to time. I'll try to get some useful information.

OK, I'll go with importlib then. Still wondering why an invalid package names chosen initially...

TWeidi commented 5 years ago

I am having the same issue when trying to open a connection to an instrument while it is disconnected. I would like to handle the raised pyvisa-py.protocols.rpc.RPCError but like @tamasgal don't know how to load pyvisa-py.

Minimal example where the error is raised: import visa rm = visa.ResourceManager('@py') instrument = rm.open_resource('TCPIP1::192.168.20.2::INSTR')

tivek commented 5 years ago

@TWeidi, I am able to reproduce your problem. The traceback is very useful here:

>>> import visa
>>> rm = visa.ResourceManager('@py')
>>> instrument = rm.open_resource('TCPIP1::192.168.20.2::INSTR')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tivek/miniconda3/envs/pyvisa-py/lib/python3.7/site-packages/pyvisa/highlevel.py", line 1724, in open_resource
    res.open(access_mode, open_timeout)
  File "/home/tivek/miniconda3/envs/pyvisa-py/lib/python3.7/site-packages/pyvisa/resources/resource.py", line 209, in open
    self.session, status = self._resource_manager.open_bare_resource(self._resource_name, access_mode, open_timeout)
  File "/home/tivek/miniconda3/envs/pyvisa-py/lib/python3.7/site-packages/pyvisa/highlevel.py", line 1681, in open_bare_resource
    return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/highlevel.py", line 194, in open
    sess = cls(session, resource_name, parsed, open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/sessions.py", line 218, in __init__
    self.after_parsing()
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/tcpip.py", line 64, in after_parsing
    self.open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/protocols/vxi11.py", line 202, in __init__
    DEVICE_CORE_VERS, open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/protocols/rpc.py", line 715, in __init__
    pmap = TCPPortMapperClient(host, open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/protocols/rpc.py", line 691, in __init__
    open_timeout)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/protocols/rpc.py", line 429, in __init__
    self.connect((open_timeout / 1000.0) + 1.0)
  File "/home/tivek/projects/pyvisa-py/pyvisa-py/protocols/rpc.py", line 459, in connect
    raise RPCError('can\'t connect to server')
pyvisa-py.protocols.rpc.RPCError: can't connect to server
>>> 

pyvisa-py.protocols.rpc.RPCError is not supposed to reach the user, which means we need to catch it and handle it sooner.

It seems TCPIPInstrSession.after_parsing() should reraise as Exception and then PyVisaLibrary.open() should return StatusCode.error_resource_not_found instead of StatusCode.success. @MatthieuDartiailh, is this the right way to handle this situation?

MatthieuDartiailh commented 5 years ago

Indeed PyVisaLibrary.open should catch errors when creating sessions. Sessions should raise errors that makes it easy to provide the right kind of error messages. However we should catch all exceptions PyVisaLibrary.open and not-only the types we expect.

We also have to make sure that we preserve enough information to debug the error. If we cannot propagate a meaningful error message, we should at the very least log them.

I do not think we need to convert the rpc.RPCError to a bare Exception, using an except Exception clause will catch everything we can be interested in.