@@ -180,7 +180,9 @@ def __init__(
180
180
self .port = port
181
181
self .hop_limit = hop_limit
182
182
self .max_buffer = max_buffer
183
- self .timestamp_nanosecond = False # This might be set by _create_socket(); False will always work
183
+
184
+ # `False` will always work, no matter the setup. This might be changed by _create_socket().
185
+ self .timestamp_nanosecond = False
184
186
185
187
# Look up multicast group address in name server and find out IP version of the first suitable target
186
188
# and then get the address family of it (socket.AF_INET or socket.AF_INET6)
@@ -295,18 +297,22 @@ def send(self, data: bytes, timeout: Optional[float] = None) -> None:
295
297
296
298
:param timeout: the timeout in seconds after which an Exception is raised is sending has failed
297
299
:param data: the data to be sent
298
- :raises OSError: if an error occurred while writing to the underlying socket
299
- :raises socket.timeout: if the timeout ran out before sending was completed (this is a subclass of
300
- *OSError*)
300
+ :raises can.CanOperationError: if an error occurred while writing to the underlying socket
301
+ :raises can.CanTimeoutError: if the timeout ran out before sending was completed
301
302
"""
302
303
if timeout != self ._last_send_timeout :
303
304
self ._last_send_timeout = timeout
304
305
# this applies to all blocking calls on the socket, but sending is the only one that is blocking
305
306
self ._socket .settimeout (timeout )
306
307
307
- bytes_sent = self ._socket .sendto (data , self ._send_destination )
308
- if bytes_sent < len (data ):
309
- raise socket .timeout ()
308
+ try :
309
+ bytes_sent = self ._socket .sendto (data , self ._send_destination )
310
+ if bytes_sent < len (data ):
311
+ raise TimeoutError ()
312
+ except TimeoutError :
313
+ raise can .CanTimeoutError () from None
314
+ except OSError as error :
315
+ raise can .CanOperationError ("failed to send via socket" ) from error
310
316
311
317
def recv (
312
318
self , timeout : Optional [float ] = None
@@ -346,17 +352,21 @@ def recv(
346
352
# fetch timestamp; this is configured in _create_socket()
347
353
if self .timestamp_nanosecond :
348
354
# Very similar to timestamp handling in can/interfaces/socketcan/socketcan.py -> capture_message()
349
- assert len (ancillary_data ) == 1 , "only requested a single extra field"
355
+ if len (ancillary_data ) != 1 :
356
+ raise can .CanOperationError (
357
+ "Only requested a single extra field but got a different amount"
358
+ )
350
359
cmsg_level , cmsg_type , cmsg_data = ancillary_data [0 ]
351
- assert (
352
- cmsg_level == socket .SOL_SOCKET and cmsg_type == SO_TIMESTAMPNS
353
- ), "received control message type that was not requested"
360
+ if cmsg_level != socket .SOL_SOCKET or cmsg_type != SO_TIMESTAMPNS :
361
+ raise can .CanOperationError (
362
+ "received control message type that was not requested"
363
+ )
354
364
# see https://man7.org/linux/man-pages/man3/timespec.3.html -> struct timespec for details
355
365
seconds , nanoseconds = struct .unpack (
356
366
self .received_timestamp_struct , cmsg_data
357
367
)
358
368
if nanoseconds >= 1e9 :
359
- raise can .CanError (
369
+ raise can .CanOperationError (
360
370
f"Timestamp nanoseconds field was out of range: { nanoseconds } not less than 1e9"
361
371
)
362
372
timestamp = seconds + nanoseconds * 1.0e-9
@@ -370,7 +380,7 @@ def recv(
370
380
self .received_timestamp_struct , result_buffer
371
381
)
372
382
if microseconds >= 1e6 :
373
- raise can .CanError (
383
+ raise can .CanOperationError (
374
384
f"Timestamp microseconds field was out of range: { microseconds } not less than 1e6"
375
385
)
376
386
timestamp = seconds + microseconds * 1e-6
0 commit comments