{"record":{"id":"cb0be2bb2e03eaa7","repo":"nautechsystems/nautilus_trader","slug":"durationnanos-overflow-in-from-millis","errorCode":null,"errorMessage":"DurationNanos overflow in from_millis","messagePattern":"DurationNanos overflow in from_millis","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":130,"sourceCode":"    /// Creates a duration from a number of whole microseconds.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the result exceeds [`DurationNanos::MAX`].\n    pub const fn try_from_micros(micros: u64) -> Result<Self, DurationNanosOutOfRangeError> {\n        Self::try_from_units(micros, NANOSECONDS_IN_MICROSECOND, \"microseconds\")\n    }\n\n    /// Creates a duration from a number of whole milliseconds.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]\n    pub const fn from_millis(millis: u64) -> Self {\n        match Self::try_from_millis(millis) {\n            Ok(duration) => duration,\n            Err(_) => panic!(\"DurationNanos overflow in from_millis\"),\n        }\n    }\n\n    /// Creates a duration from a number of whole milliseconds.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the result exceeds [`DurationNanos::MAX`].\n    pub const fn try_from_millis(millis: u64) -> Result<Self, DurationNanosOutOfRangeError> {\n        Self::try_from_units(millis, NANOSECONDS_IN_MILLISECOND, \"milliseconds\")\n    }\n\n    /// Creates a duration from a number of whole seconds.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L112-L148","documentation":"`DurationNanos::from_millis` converts whole milliseconds (u64) into a nanosecond-based duration. It is a panicking (`#[must_use] const fn`) wrapper around the fallible `try_from_millis`, so when `millis * 1_000_000` exceeds `DurationNanos::MAX` it intentionally panics rather than returning a Result. The library throws it because the requested duration cannot be represented in the u64 nanosecond domain.","triggerScenarios":"Calling `DurationNanos::from_millis(m)` where `m > u64::MAX / 1_000_000` (i.e. `m >= 18_446_744_073_709` ms, roughly 213.5 days), so the millisecond-to-nanosecond multiplication overflows u64 and the `Err(_)` arm of the match panics.","commonSituations":"Computing a timeout/backoff from a user- or config-supplied millisecond value with no upper bound check; multiplying durations (e.g. days or weeks expressed in ms) before passing them in; fuzzing or property tests with u64::MAX; config files where a value is accidentally in nanoseconds or microseconds instead of milliseconds.","solutions":["Use the fallible `DurationNanos::try_from_millis(millis)` and handle the Err case instead of panicking.","Validate the input before calling: reject values greater than `u64::MAX / 1_000_000`.","Correct the unit of the upstream value (config/env often passes nanos or micros mislabeled as millis).","Clamp the value to `DurationNanos::MAX` nanoseconds converted back to milliseconds if saturation is acceptable."],"exampleFix":"// before\nlet dur = DurationNanos::from_millis(cfg_timeout_ms);\n\n// after\nlet dur = DurationNanos::try_from_millis(cfg_timeout_ms)\n    .unwrap_or(DurationNanos::MAX); // or surface the error to the caller","handlingStrategy":"validation","validationCode":"const MAX_FROM_MILLIS: u64 = u64::MAX / 1_000_000;\nfn can_convert_millis(m: u64) -> bool { m <= MAX_FROM_MILLIS }","typeGuard":"fn fits_duration_millis(m: u64) -> Option<DurationNanos> {\n    DurationNanos::try_from_millis(m).ok()\n}","tryCatchPattern":null,"preventionTips":["Prefer try_from_millis in application code; reserve from_millis for const contexts with known-good literals.","Sanity-check configured millisecond values against a plausible maximum at load time.","Never use u64::MAX as a 'forever' sentinel; define an explicit constant within range.","Document and enforce the unit (ms vs us vs ns) of every duration config field."],"tags":["rust","panic","integer-overflow","duration"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}