@@ -92,7 +92,9 @@ def __init__(
92
92
check_msgpack_installed ()
93
93
94
94
if receive_own_messages :
95
- raise NotImplementedError ("receiving own messages is not yet implemented" )
95
+ raise can .CanInterfaceNotImplementedError (
96
+ "receiving own messages is not yet implemented"
97
+ )
96
98
97
99
super ().__init__ (channel , ** kwargs )
98
100
@@ -105,7 +107,14 @@ def _recv_internal(self, timeout: Optional[float]):
105
107
return None , False
106
108
107
109
data , _ , timestamp = result
108
- can_message = unpack_message (data , replace = {"timestamp" : timestamp })
110
+ try :
111
+ can_message = unpack_message (
112
+ data , replace = {"timestamp" : timestamp }, check = True
113
+ )
114
+ except Exception as exception :
115
+ raise can .CanOperationError (
116
+ "could not unpack received message"
117
+ ) from exception
109
118
110
119
if not self .is_fd and can_message .is_fd :
111
120
return None , False
@@ -114,7 +123,9 @@ def _recv_internal(self, timeout: Optional[float]):
114
123
115
124
def send (self , message : can .Message , timeout : Optional [float ] = None ) -> None :
116
125
if not self .is_fd and message .is_fd :
117
- raise RuntimeError ("cannot send FD message over bus with CAN FD disabled" )
126
+ raise can .CanOperationError (
127
+ "cannot send FD message over bus with CAN FD disabled"
128
+ )
118
129
119
130
data = pack_message (message )
120
131
self ._multicast .send (data , timeout )
@@ -149,7 +160,10 @@ def _detect_available_configs() -> List[AutoDetectedConfig]:
149
160
150
161
151
162
class GeneralPurposeUdpMulticastBus :
152
- """A general purpose send and receive handler for multicast over IP/UDP."""
163
+ """A general purpose send and receive handler for multicast over IP/UDP.
164
+
165
+ However, it raises CAN-specific exceptions for convenience.
166
+ """
153
167
154
168
def __init__ (
155
169
self , group : str , port : int , hop_limit : int , max_buffer : int = 4096
@@ -178,7 +192,9 @@ def __init__(
178
192
if sock is not None :
179
193
self ._socket = sock
180
194
else :
181
- raise RuntimeError ("could not connect to a multicast IP network" )
195
+ raise can .CanInitializationError (
196
+ "could not connect to a multicast IP network"
197
+ )
182
198
183
199
# used in recv()
184
200
self .received_timestamp_struct = "@ll"
@@ -193,8 +209,10 @@ def _create_socket(self, address_family: socket.AddressFamily) -> socket.socket:
193
209
"""Creates a new socket. This might fail and raise an exception!
194
210
195
211
:param address_family: whether this is of type `socket.AF_INET` or `socket.AF_INET6`
196
- :raises OSError: if the socket could not be opened or configured correctly; in this case, it is
197
- guaranteed to be closed/cleaned up
212
+
213
+ :raises can.CanInitializationError:
214
+ if the socket could not be opened or configured correctly; in this case, it is
215
+ guaranteed to be closed/cleaned up
198
216
"""
199
217
# create the UDP socket
200
218
# this might already fail but then there is nothing to clean up
@@ -243,7 +261,9 @@ def _create_socket(self, address_family: socket.AddressFamily) -> socket.socket:
243
261
log .warning ("Could not close partly configured socket: %s" , close_error )
244
262
245
263
# still raise the error
246
- raise error
264
+ raise can .CanInitializationError (
265
+ "could not create or configure socket"
266
+ ) from error
247
267
248
268
def send (self , data : bytes , timeout : Optional [float ] = None ) -> None :
249
269
"""Send data to all group members. This call blocks.
@@ -283,7 +303,9 @@ def recv(
283
303
ready_receive_sockets , _ , _ = select .select ([self ._socket ], [], [], timeout )
284
304
except socket .error as exc :
285
305
# something bad (not a timeout) happened (e.g. the interface went down)
286
- raise can .CanError (f"Failed to wait for IP/UDP socket: { exc } " )
306
+ raise can .CanOperationError (
307
+ f"Failed to wait for IP/UDP socket: { exc } "
308
+ ) from exc
287
309
288
310
if ready_receive_sockets : # not empty
289
311
# fetch data & source address
0 commit comments