Skip to content

Commit f2ad16c

Browse files
committed
Fix exceptions (don't use asserts, always raise CAN errors)
1 parent ae36ea7 commit f2ad16c

File tree

1 file changed

+23
-13
lines changed
  • can/interfaces/udp_multicast

1 file changed

+23
-13
lines changed

can/interfaces/udp_multicast/bus.py

+23-13
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ def __init__(
180180
self.port = port
181181
self.hop_limit = hop_limit
182182
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
184186

185187
# Look up multicast group address in name server and find out IP version of the first suitable target
186188
# 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:
295297
296298
:param timeout: the timeout in seconds after which an Exception is raised is sending has failed
297299
: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
301302
"""
302303
if timeout != self._last_send_timeout:
303304
self._last_send_timeout = timeout
304305
# this applies to all blocking calls on the socket, but sending is the only one that is blocking
305306
self._socket.settimeout(timeout)
306307

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
310316

311317
def recv(
312318
self, timeout: Optional[float] = None
@@ -346,17 +352,21 @@ def recv(
346352
# fetch timestamp; this is configured in _create_socket()
347353
if self.timestamp_nanosecond:
348354
# 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+
)
350359
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+
)
354364
# see https://man7.org/linux/man-pages/man3/timespec.3.html -> struct timespec for details
355365
seconds, nanoseconds = struct.unpack(
356366
self.received_timestamp_struct, cmsg_data
357367
)
358368
if nanoseconds >= 1e9:
359-
raise can.CanError(
369+
raise can.CanOperationError(
360370
f"Timestamp nanoseconds field was out of range: {nanoseconds} not less than 1e9"
361371
)
362372
timestamp = seconds + nanoseconds * 1.0e-9
@@ -370,7 +380,7 @@ def recv(
370380
self.received_timestamp_struct, result_buffer
371381
)
372382
if microseconds >= 1e6:
373-
raise can.CanError(
383+
raise can.CanOperationError(
374384
f"Timestamp microseconds field was out of range: {microseconds} not less than 1e6"
375385
)
376386
timestamp = seconds + microseconds * 1e-6

0 commit comments

Comments
 (0)