{"record":{"id":"2cbbda9028282b8b","repo":"embassy-rs/embassy","slug":"overflow-when-adding-durations","errorCode":null,"errorMessage":"overflow when adding durations","messagePattern":"overflow when adding durations","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-time/src/duration.rs","lineNumber":216,"sourceCode":"        self.ticks.checked_mul(rhs as _).map(|ticks| Duration { ticks })\n    }\n\n    /// Divides one `Duration` by a scalar `u32`, returning a new `Duration` or `None` in the event of an overflow.\n    pub fn checked_div(self, rhs: u32) -> Option<Duration> {\n        self.ticks.checked_div(rhs as _).map(|ticks| Duration { ticks })\n    }\n}\n\nimpl Add for Duration {\n    type Output = Duration;\n\n    /// Computes `Duration + Duration`. [Read more](Add)\n    ///\n    /// ## Panics\n    ///\n    /// Panics if the computed duration overflows.\n    fn add(self, rhs: Duration) -> Duration {\n        self.checked_add(rhs).expect(\"overflow when adding durations\")\n    }\n}\n\nimpl AddAssign for Duration {\n    /// Computes `Duration += Duration`. [Read more](AddAssign)\n    ///\n    /// ## Panics\n    ///\n    /// Panics if the computed duration overflows.\n    fn add_assign(&mut self, rhs: Duration) {\n        *self = *self + rhs;\n    }\n}\n\nimpl Sub for Duration {\n    type Output = Duration;\n\n    /// Computes `Duration - Duration`. [Read more](Sub)","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-time/src/duration.rs#L198-L234","documentation":"embassy-time's `Duration` implements `Add` via `checked_add`; if the resulting tick count exceeds the internal representation (i64 microseconds / u64 ticks), `.expect(\"overflow when adding durations\")` panics. It matches std's documented behavior that `Duration + Duration` panics on overflow.","triggerScenarios":"`a + b` where the combined tick count exceeds `Duration`'s maximum (e.g. adding two near-max durations, or accumulating durations in a loop without saturation).","commonSituations":"Computing deadlines from very large timeouts; summing user-provided durations; arithmetic on `Duration::MAX`; integer unit confusion (seconds vs micros) inflating values.","solutions":["Use `checked_add` and handle `None` yourself (clamp to `Duration::MAX` or return an error)","Clamp inputs: `a.saturating_add(b)` if available, or `a.checked_add(b).unwrap_or(Duration::MAX)`","Validate user-supplied timeout magnitudes before arithmetic"],"exampleFix":"// before\nlet total = a + b; // panics on overflow\n// after\nlet total = a.checked_add(b).unwrap_or(Duration::MAX);","handlingStrategy":"try-catch","validationCode":"fn safe_add(a: embassy_time::Duration, b: embassy_time::Duration) -> embassy_time::Duration {\n    a.checked_add(b).unwrap_or(embassy_time::Duration::MAX)\n}","typeGuard":null,"tryCatchPattern":"// Rust panics are not catchable in embedded; use checked API instead:\nlet total = match a.checked_add(b) {\n    Some(t) => t,\n    None => Duration::MAX, // or return Err\n};","preventionTips":["Use checked_add instead of `+` for untrusted duration inputs","Clamp timeouts to sane maxima before arithmetic","Beware unit conversions that inflate tick counts"],"tags":["arithmetic","duration","overflow","panic"],"backgroundTag":"arithmetic-overflow","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}