{"record":{"id":"241a1e1857a0a7fc","repo":"nautechsystems/nautilus_trader","slug":"python-on-degrade-failed-e","errorCode":null,"errorMessage":"Python on_degrade failed: {e}","messagePattern":"Python on_degrade failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/python/actor.rs","lineNumber":1045,"sourceCode":"\n    fn on_resume(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_resume()\n            .map_err(|e| anyhow::anyhow!(\"Python on_resume failed: {e}\"))\n    }\n\n    fn on_reset(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_reset()\n            .map_err(|e| anyhow::anyhow!(\"Python on_reset failed: {e}\"))\n    }\n\n    fn on_dispose(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_dispose()\n            .map_err(|e| anyhow::anyhow!(\"Python on_dispose failed: {e}\"))\n    }\n\n    fn on_degrade(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_degrade()\n            .map_err(|e| anyhow::anyhow!(\"Python on_degrade failed: {e}\"))\n    }\n\n    fn on_fault(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_fault()\n            .map_err(|e| anyhow::anyhow!(\"Python on_fault failed: {e}\"))\n    }\n\n    fn on_save(&self) -> anyhow::Result<IndexMap<String, Vec<u8>>> {\n        self.dispatch_on_save()\n            .map_err(|e| anyhow::anyhow!(\"Python on_save failed: {e}\"))\n    }\n\n    fn on_load(&mut self, state: IndexMap<String, Vec<u8>>) -> anyhow::Result<()> {\n        self.dispatch_on_load(&state)\n            .map_err(|e| anyhow::anyhow!(\"Python on_load failed: {e}\"))\n    }\n\n    fn on_time_event(&mut self, event: &TimeEvent) -> anyhow::Result<()> {","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/python/actor.rs#L1027-L1063","documentation":"Raised by the Rust `DataActor` bridge when the Python actor's `on_degrade()` callback raises an exception. The `dispatch_on_degrade()` call forwards into Python and the exception is rewrapped in this anyhow error. Degrade is invoked when the component enters a degraded (reduced-functionality) operational state.","triggerScenarios":"Any exception thrown in the user's Python `on_degrade`, e.g. canceling data subscriptions or reducing exposure and hitting a failed call, None attribute, or bad argument inside the callback.","commonSituations":"Live trading venue degradation where on_degrade unsubscribes feeds and the unsubscribe path raises; strategies that downgrade indicators but reference an indicator that was never registered.","solutions":["Extract the Python traceback from the error message and fix the raising line in on_degrade.","Wrap degrade actions in try/except so partial degradation still completes and logs failures.","Verify every object on_degrade touches exists in both normal and degraded startup paths.","Simulate a degrade event in a test to exercise the callback before going live."],"exampleFix":"// before (Python)\ndef on_degrade(self):\n    self.unsubscribe(self.bar_type)\n\n// after\ndef on_degrade(self):\n    try:\n        self.unsubscribe(self.bar_type)\n    except Exception as e:\n        self.log.warning(f\"degrade unsubscribe failed: {e}\")","handlingStrategy":"try-catch","validationCode":"# check degradation preconditions\nassert getattr(self, 'subscriptions', None) is not None, 'subscriptions must exist before degrade'","typeGuard":"def can_degrade(actor):\n    return callable(getattr(actor, 'on_degrade', None)) and getattr(actor, 'is_running', False)","tryCatchPattern":"def on_degrade(self):\n    try:\n        ...  # reduce functionality\n    except Exception as e:\n        self.log.warning(f\"on_degrade partial failure: {e}\")","preventionTips":["Treat degrade as best-effort: log failures, never raise.","Test degrade under staging conditions (feed outages) before live use.","Verify every object touched in on_degrade exists in all startup paths.","Keep degrade actions independent so one failure doesn't abort the rest."],"tags":["python","actor-lifecycle","callback-exception","rust-bridge"],"backgroundTag":"python-callback-raised-exception","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}