{"record":{"id":"c746cd7d0bfeadf6","repo":"nautechsystems/nautilus_trader","slug":"python-on-fault-failed-e-c746cd","errorCode":null,"errorMessage":"Python on_fault failed: {e}","messagePattern":"Python on_fault failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/trading/src/python/strategy.rs","lineNumber":1091,"sourceCode":"\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<()> {\n        route_time_event(self, event);\n        self.dispatch_on_time_event(event)\n            .map_err(|e| anyhow::anyhow!(\"Python on_time_event failed: {e}\"))\n    }\n","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/trading/src/python/strategy.rs#L1073-L1109","documentation":"The strategy's Python-level `on_fault` callback raised an exception. The Rust wrapper calls `dispatch_on_fault()` (crates/trading/src/python/strategy.rs:377) via `call_method0`; any exception escaping the Python method is wrapped as `anyhow::anyhow!(\"Python on_fault failed: {e}\")` at strategy.rs:1091. The interpolated `{e}` contains the real Python traceback cause.","triggerScenarios":"A FAULT state transition triggers the registered actor/strategy hook; the user's Python `on_fault` method raises (e.g. attempting to use resources that are themselves in a faulted state, or an unhandled error in fault reporting/alerting code).","commonSituations":"Fault handlers that try to publish notifications through a broken network client; `on_fault` referencing `self` state that was never initialized because the fault occurred during start-up; exception inside a `finally`-style cleanup racing with shutdown.","solutions":["Inspect the `{e}` payload for the underlying Python exception and fix the fault-handler code.","Make `on_fault` defensive: never call out to network/external systems without try/except and logging.","Ensure all attributes used in `on_fault` are initialized in `__init__` so the handler works even on early-life faults.","Confirm the method signature is `def on_fault(self)` with no extra required parameters."],"exampleFix":"// before\ndef on_fault(self):\n    self.alerts.send(\"strategy faulted\")  # raises when alert service is down\n\n// after\ndef on_fault(self):\n    try:\n        self.alerts.send(\"strategy faulted\")\n    except Exception as e:\n        self.log.error(f\"could not send fault alert: {e}\")","handlingStrategy":"try-catch","validationCode":"import inspect\ndef _check_fault_hook(strategy):\n    fn = getattr(strategy, \"on_fault\", None)\n    return callable(fn) and len(inspect.signature(fn).parameters) == 1","typeGuard":"def has_hook(obj, name):\n    return callable(getattr(obj, name, None))","tryCatchPattern":"try:\n    self.on_fault()\nexcept Exception as e:\n    self.log.error(f\"on_fault handler itself failed: {e}\")","preventionTips":["Treat on_fault as best-effort: never raise, only log and record.","Avoid using faulted subsystems (network clients) inside the fault handler without guards.","Add a unit test that calls on_fault on a freshly constructed strategy (pre-start state).","Keep the method signature exactly def on_fault(self)."],"tags":["python","strategy","lifecycle-hook","fault-handling"],"backgroundTag":"python-callback-failed","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"}