{"record":{"id":"c30dc0ac36a7d118","repo":"nautechsystems/nautilus_trader","slug":"durationnanos-overflow-in-from-micros","errorCode":null,"errorMessage":"DurationNanos overflow in from_micros","messagePattern":"DurationNanos overflow in from_micros","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":108,"sourceCode":"    /// The maximum duration representable by this type.\n    pub const MAX: Self = Self(u64::MAX);\n\n    /// Creates a duration from an exact nanosecond count.\n    #[must_use]\n    pub const fn new(nanos: u64) -> Self {\n        Self(nanos)\n    }\n\n    /// Creates a duration from a number of whole microseconds.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]\n    pub const fn from_micros(micros: u64) -> Self {\n        match Self::try_from_micros(micros) {\n            Ok(duration) => duration,\n            Err(_) => panic!(\"DurationNanos overflow in from_micros\"),\n        }\n    }\n\n    /// 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]","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L90-L126","documentation":"`DurationNanos::from_micros` is the panicking constructor for durations from whole microseconds; since `DurationNanos` is a `u64` nanosecond count, a microsecond value above `u64::MAX / 1_000` (~18446744073709551 micros, about 584,000 years) overflows and panics with this message. The library pairs every panicking constructor with a `try_from_micros` variant returning `DurationNanosOutOfRangeError` for callers that want fallible handling. In practice this only fires with extreme or bogus (unvalidated/huge) u64 inputs.","triggerScenarios":"Calling `DurationNanos::from_micros(micros)` with `micros > u64::MAX / NANOSECONDS_IN_MICROSECOND` (18446744073709551); e.g. converting a raw unvalidated u64 from config, FFI, or a wire protocol.","commonSituations":"Passing seconds/milliseconds accidentally as microseconds (unit confusion multiplying by 1000 too many times); unvalidated config values like `u64::MAX` sentinels used as durations; FFI or deserialized data with corrupted duration fields.","solutions":["Use the fallible `DurationNanos::try_from_micros(micros)` and handle `DurationNanosOutOfRangeError`.","Check `micros <= u64::MAX / 1_000` (18446744073709551) before calling `from_micros`.","Audit the value's unit — the input may actually be seconds/millis being multiplied into micros twice.","Validate config/FFI duration values against a sane upper bound before conversion."],"exampleFix":"// before\nlet duration = DurationNanos::from_micros(config_micros); // panics on huge values\n// after\nlet duration = DurationNanos::try_from_micros(config_micros)\n    .map_err(|e| anyhow!(\"invalid duration config: {e}\"))?;","handlingStrategy":"try-catch","validationCode":"const NANOS_PER_MICRO: u64 = 1_000;\nfn micros_in_range(micros: u64) -> bool {\n    micros <= u64::MAX / NANOS_PER_MICRO // 18446744073709551\n}","typeGuard":"fn fits_duration_nanos(micros: u64) -> bool {\n    micros.checked_mul(1_000).is_some()\n}","tryCatchPattern":"// Rust panics are not catchable; use the fallible constructor\nlet duration = match DurationNanos::try_from_micros(micros) {\n    Ok(d) => d,\n    Err(e) => return Err(anyhow!(\"duration out of range: {e}\")),\n};","preventionTips":["Use `try_from_micros`/`try_from_millis`/`try_from_secs` in non-test code","Double-check unit conversion chains — accidental double ×1000 multipliers cause overflow","Reject sentinel values like u64::MAX from config/FFI before duration conversion","Bound user-configured durations to a sane maximum (e.g. 100 years)"],"tags":["rust","panic","overflow","duration","nanoseconds"],"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"}