python-can-isotp icon indicating copy to clipboard operation
python-can-isotp copied to clipboard

isotp.socket() behavior deviates from python sockets on timeouts

Open mrnuke opened this issue 4 years ago • 1 comments

A standard python socket would encounter a socket.timeout Exception on recv() if no data came in. The can-isotp package, on the other hand, catches the exception and converts it into a return None.

I think this is wrong for several reasons:

  1. It deviates from the programmer's expectations that a can-isotp socket behaves like a regular python socket.
  2. The can-isotp package may not know if a timeout is an error or normal behavior. It is up to application code to determine.
  3. It obscures that the application may be waiting for IO before reaching a timeout.
  4. Code that expects to catch a timeout exception may end up generating a TypeError as it works with the None object.

Proposal:

When istop.socket.recv() times out, the socket.timeout error should either be passed down, or converted and re-raised explicitly as a TimeoutError().

Example

sock = isotp.socket()
sock.set_opts(txpad=0xcc)
sock.bind("can0", isotp.Address(txid=0x7e0, rxid=0x7e8))

bogus_msg = bytes([0xde, 0xad, 0xc0, 0xff, 0xee])
answer sock.send(bogus_msg)
try:
	answer = sock.recv()
except socket.error as err:
	# EXPECTATION: we hit this handler
	return

# REALITY: We get a None object when we expect actual data
# The line below will explode with an isotp socket
print(len(answer))

mrnuke avatar Jun 21 '21 15:06 mrnuke

Indeed. I think you are right. i will have to double check not to break anything that is based on that behaviour.

pylessard avatar Aug 05 '21 17:08 pylessard

Quick update. I'm starting to look at redesigning how reception is done. This will be fixed. There will be a breaking change, causing v2.0

pylessard avatar Oct 23 '23 02:10 pylessard

This has been corrected in the newly created v2.x branch. Closing the issue.

thank you

pylessard avatar Oct 30 '23 01:10 pylessard