{"record":{"id":"ccaaa9c4d66472ad","repo":"nautechsystems/nautilus_trader","slug":"failed-to-calculate-slippage-e","errorCode":null,"errorMessage":"Failed to calculate slippage: {e}","messagePattern":"Failed to calculate slippage: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/quote.rs","lineNumber":237,"sourceCode":"            Err(e) => anyhow::bail!(\"Failed to calculate price impact: {e}\"),\n        }\n    }\n\n    /// Calculates slippage in basis points (requires token references for decimal adjustment).\n    ///\n    /// Slippage includes both price impact and fees, representing the total\n    /// deviation from the spot price before the swap. This measures the total\n    /// cost to the trader.\n    ///\n    /// # Returns\n    /// Total slippage in basis points (10000 = 100%)\n    ///\n    /// # Errors\n    /// Returns error if price calculations fail\n    pub fn get_slippage_bps(&mut self) -> anyhow::Result<u32> {\n        match self.check_if_trade_info_initialized() {\n            Ok(trade_info) => trade_info.get_slippage_bps(),\n            Err(e) => anyhow::bail!(\"Failed to calculate slippage: {e}\"),\n        }\n    }\n\n    /// # Errors\n    ///\n    /// Returns an error if the actual slippage exceeds the maximum slippage tolerance.\n    pub fn validate_slippage_tolerance(&mut self, max_slippage_bps: u32) -> anyhow::Result<()> {\n        let actual_slippage = self.get_slippage_bps()?;\n        if actual_slippage > max_slippage_bps {\n            anyhow::bail!(\n                \"Slippage {actual_slippage} bps exceeds tolerance {max_slippage_bps} bps\"\n            );\n        }\n        Ok(())\n    }\n\n    /// Validates that the quote satisfied an exact output request.\n    ///","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/quote.rs#L219-L255","documentation":"This public `get_slippage_bps` wraps `SwapTradeInfo::get_slippage_bps` and converts an uninitialized-trade-info failure into `Failed to calculate slippage: {e}`. Like its price-impact counterpart, it preserves the root cause text from `check_if_trade_info_initialized` while adding metric-specific context.","triggerScenarios":"Calling `get_slippage_bps()` (directly, or indirectly via `validate_slippage_tolerance`) on a quote created with `trade_info: None` without first calling `calculate_trade_info()`.","commonSituations":"Calling `validate_slippage_tolerance` on a freshly constructed quote; dropping the initialization call during refactor; assuming the constructor computes trade info when it does not.","solutions":["Invoke `quote.calculate_trade_info()` before any slippage-related call.","Ensure `validate_slippage_tolerance` is only called after trade-info initialization (it delegates to this method).","Centralize quote construction in a factory that always computes trade info.","Match on the error to distinguish uninitialized state from genuine slippage computation failures."],"exampleFix":"// before\nlet mut quote = Quote::new(pool, amount_in);\nquote.validate_slippage_tolerance(100)?;\n// after\nlet mut quote = Quote::new(pool, amount_in);\nquote.calculate_trade_info()?;\nquote.validate_slippage_tolerance(100)?;","handlingStrategy":"try-catch","validationCode":"quote.calculate_trade_info()?; // required before get_slippage_bps/validate_slippage_tolerance","typeGuard":null,"tryCatchPattern":"let slippage_bps = match quote.get_slippage_bps() {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"Failed to calculate slippage\") => {\n        quote.calculate_trade_info()?;\n        quote.get_slippage_bps()?\n    },\n    Err(e) => return Err(e),\n};","preventionTips":["Remember validate_slippage_tolerance delegates here; initialize trade info before either call.","Centralize quote creation so trade-info initialization is never optional.","Distinguish the uninitialized-state wrapper error from genuine slippage math failures by message.","Add an integration test covering the construct -> read-metrics ordering."],"tags":["defi","quote","slippage","error-wrapping"],"backgroundTag":"invalid-state-transition","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"}