{"record":{"id":"a85ace93f8169ef3","repo":"nautechsystems/nautilus_trader","slug":"failed-to-calculate-price-impact-e","errorCode":null,"errorMessage":"Failed to calculate price impact: {e}","messagePattern":"Failed to calculate price impact: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/quote.rs","lineNumber":219,"sourceCode":"            self.amount1.unsigned_abs()\n        }\n    }\n\n    /// Calculates price impact in basis points (requires token references for decimal adjustment).\n    ///\n    /// Price impact measures the market movement caused by the swap size,\n    /// excluding fees. This is the percentage change in spot price from\n    /// before to after the swap.\n    ///\n    /// # Returns\n    /// Price impact in basis points (10000 = 100%)\n    ///\n    /// # Errors\n    /// Returns error if price calculations fail\n    pub fn get_price_impact_bps(&mut self) -> anyhow::Result<u32> {\n        match self.check_if_trade_info_initialized() {\n            Ok(trade_info) => trade_info.get_price_impact_bps(),\n            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}\"),","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/quote.rs#L201-L237","documentation":"This public `get_price_impact_bps` wraps the inner `SwapTradeInfo::get_price_impact_bps` call and, when trade-info initialization fails (i.e. `trade_info` is None), re-raises the underlying error with the message `Failed to calculate price impact: {e}`. It is an error-context wrapper: the root cause is the uninitialized trade info reported by `check_if_trade_info_initialized`.","triggerScenarios":"Calling `get_price_impact_bps()` on a quote whose `trade_info` was never initialized via `calculate_trade_info()`. Observed in tests as `test_metric_errors_propagate_from_trade_info`.","commonSituations":"Forgetting the `calculate_trade_info()` step before reading price impact; early-return paths that skip initialization; copying example code that initialized slippage but not price impact (shared init means either order fails identically).","solutions":["Call `calculate_trade_info()` on the quote before requesting price impact.","Read the wrapped inner message to confirm the root cause is uninitialized trade info, not a math failure.","Guard with a helper that checks/initializes trade info once per quote.","If trade info can legitimately be absent, handle the Result instead of `?`-propagating into caller code."],"exampleFix":"// before\nlet mut quote = Quote::new(pool, amount_in);\nlet impact_bps = quote.get_price_impact_bps()?;\n// after\nlet mut quote = Quote::new(pool, amount_in);\nquote.calculate_trade_info()?;\nlet impact_bps = quote.get_price_impact_bps()?;","handlingStrategy":"try-catch","validationCode":"quote.calculate_trade_info()?; // avoids the wrapper error entirely","typeGuard":null,"tryCatchPattern":"let impact_bps = match quote.get_price_impact_bps() {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"Failed to calculate price impact\") => {\n        quote.calculate_trade_info()?;\n        quote.get_price_impact_bps()?\n    },\n    Err(e) => return Err(e),\n};","preventionTips":["Read the wrapped inner message to identify the root cause (uninitialized trade info).","Initialize trade info eagerly at quote construction to make the wrapper a non-issue.","Wrap quote usage in a small facade that guarantees calculate_trade_info() was called.","Log full error chains, not just the outer message, when diagnosing."],"tags":["defi","quote","error-wrapping","initialization"],"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"}