{"record":{"id":"4126c4adf2670c91","repo":"nautechsystems/nautilus_trader","slug":"durationnanos-overflow-in-from-secs","errorCode":null,"errorMessage":"DurationNanos overflow in from_secs","messagePattern":"DurationNanos overflow in from_secs","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":152,"sourceCode":"    /// 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]\n    pub const fn from_secs(secs: u64) -> Self {\n        match Self::try_from_secs(secs) {\n            Ok(duration) => duration,\n            Err(_) => panic!(\"DurationNanos overflow in from_secs\"),\n        }\n    }\n\n    /// Creates a duration from a number of whole seconds.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the result exceeds [`DurationNanos::MAX`].\n    pub const fn try_from_secs(secs: u64) -> Result<Self, DurationNanosOutOfRangeError> {\n        Self::try_from_units(secs, NANOSECONDS_IN_SECOND, \"seconds\")\n    }\n\n    /// Creates a duration from a number of whole minutes.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L134-L170","documentation":"`DurationNanos::from_secs` converts whole seconds (u64) into nanoseconds. It panics when `secs * 1_000_000_000` exceeds `DurationNanos::MAX`, since the result cannot be stored in the u64 nanosecond representation. The panic is deliberate: this is the const, infallible-facing constructor documented as 'Panics if the result exceeds DurationNanos::MAX'.","triggerScenarios":"Calling `DurationNanos::from_secs(s)` with `s > u64::MAX / 1_000_000_000` (i.e. `s >= 18_446_744_073`, about 584 years), causing the checked multiplication inside `try_from_secs` to fail and the `Err(_)` arm to panic.","commonSituations":"Configuration values like 'ttl_seconds' or 'expiry_seconds' set absurdly high (e.g. u64::MAX as 'forever'); converting a lifetime or lease duration to seconds then feeding it in; test code probing extreme values.","solutions":["Use `DurationNanos::try_from_secs(secs)` and handle Err explicitly.","Bound-check the input: reject values greater than `u64::MAX / 1_000_000_000` before construction.","Clamp to `DurationNanos::MAX` when 'as long as possible' semantics are intended.","Fix upstream units if the config value is already in nanoseconds/milliseconds."],"exampleFix":"// before\nlet dur = DurationNanos::from_secs(ttl_secs);\n\n// after\nlet dur = match DurationNanos::try_from_secs(ttl_secs) {\n    Ok(d) => d,\n    Err(_) => return Err(anyhow!(\"ttl_secs {ttl_secs} too large for DurationNanos\")),\n};","handlingStrategy":"validation","validationCode":"const MAX_FROM_SECS: u64 = u64::MAX / 1_000_000_000;\nfn can_convert_secs(s: u64) -> bool { s <= MAX_FROM_SECS }","typeGuard":"fn fits_duration_secs(s: u64) -> Option<DurationNanos> {\n    DurationNanos::try_from_secs(s).ok()\n}","tryCatchPattern":null,"preventionTips":["Use try_from_secs and map Err to a domain error in fallible paths.","Cap TTL/expiry config values to a sane maximum (e.g. 100 years) during validation.","Avoid u64::MAX sentinels for 'never expires'; use Option<DurationNanos> instead."],"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"}