error.rs
⎇
Raw
1/// A datagram could not be turned into a [`crate::Message`].
2///
3/// Everything here is a *structural* failure: the bytes cannot be parsed at
4/// all. Values that parse but are nonsensical (a latitude of 300°, a timestamp
5/// in 1970) are not errors at this layer — see [`ValidationError`].
6#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
7pub enum DecodeError {
8 #[error("datagram too short: {0} bytes, minimum is {min}", min = crate::MIN_DATAGRAM)]
9 TooShort(usize),
10
11 #[error("datagram too long: {0} bytes, maximum is {max}", max = crate::MAX_DATAGRAM)]
12 TooLong(usize),
13
14 #[error("unsupported protocol version {0}, this build speaks {ours}", ours = crate::VERSION)]
15 BadVersion(u8),
16
17 #[error("unknown message type 0x{0:x}")]
18 BadMsgType(u8),
19
20 /// The AEAD tag did not verify. Never answer this — see
21 /// [`crate::may_respond`] and the "no oracle" rule.
22 #[error("authentication failed")]
23 AuthFailed,
24
25 #[error("{what}: expected {expected} payload bytes, got {actual}")]
26 BadPayloadLen {
27 what: &'static str,
28 expected: usize,
29 actual: usize,
30 },
31
32 #[error("LOC point count {0} out of range 1..={max}", max = crate::MAX_POINTS)]
33 BadPointCount(usize),
34
35 #[error("ACK nonce count {0} out of range 1..={max}", max = crate::MAX_POINTS)]
36 BadNonceCount(usize),
37
38 #[error("unknown {field} discriminant {value}")]
39 BadEnum { field: &'static str, value: u8 },
40}
41
42/// A message parsed cleanly but carries values the server should not store.
43///
44/// Kept separate from [`DecodeError`] on purpose: the codec stays a total
45/// function over well-formed byte strings, so the round-trip property holds
46/// without carve-outs, and policy lives where policy belongs.
47#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
48pub enum ValidationError {
49 #[error("latitude {0} out of range ±90e7")]
50 Latitude(i32),
51
52 #[error("longitude {0} out of range ±180e7")]
53 Longitude(i32),
54
55 #[error("bearing {0} centidegrees out of range 0..=35999")]
56 Bearing(u16),
57
58 #[error("battery {0}% out of range 0..=100")]
59 Battery(u8),
60
61 #[error("timestamp {ts} is {off_by}s outside the accepted window around {now}")]
62 Timestamp { ts: u32, now: u32, off_by: i64 },
63}
64