{"record":{"id":"55407df8b68792e0","repo":"SeaQL/sea-orm","slug":"failed-to-acquire-mocker-55407d","errorCode":null,"errorMessage":"Failed to acquire mocker","messagePattern":"Failed to acquire mocker","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/driver/mock.rs","lineNumber":209,"sourceCode":"        #[cfg(feature = \"sync\")]\n        {\n            match self.query_all(statement.clone()) {\n                Ok(v) => Box::new(v.into_iter().map(Ok)),\n                Err(e) => Box::new(Some(Err(e)).into_iter()),\n            }\n        }\n    }\n\n    /// Create a statement block  of SQL statements that execute together.\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn begin(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .begin()\n    }\n\n    /// Commit a transaction atomically to the database\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn commit(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .commit()\n    }\n\n    /// Roll back a faulty transaction\n    ///","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/src/driver/mock.rs#L191-L227","documentation":"MockTransaction (or MockDatabase) begin() locks the mocker mutex with expect(\"Failed to acquire mocker\"). A poisoned mutex — caused by a panic in another thread while the lock was held — makes lock() return Err and this expect panics. The mocked transaction cannot even be started.","triggerScenarios":"Calling begin() on a mock transaction after a prior panic occurred while another thread held the mocker lock (e.g. a mock callback asserted on unexpected SQL and panicked).","commonSituations":"Test suites running mocked DB operations concurrently on a shared connector; one failing test poisons the lock and cascades 'Failed to acquire mocker' panics into all later tests.","solutions":["Diagnose and fix the root panic that poisoned the mutex (run the offending test alone to see its original panic).","Isolate tests: one MockDatabase per test, no shared connector across threads.","Recover from poisoning via lock().unwrap_or_else(|p| p.into_inner()) if shared state remains consistent.","Make mock callbacks return Result instead of panicking on unexpected statements."],"exampleFix":"// before\nself.mocker.lock().expect(\"Failed to acquire mocker\").begin()\n// after\nself.mocker.lock().unwrap_or_else(|poisoned| poisoned.into_inner()).begin()","handlingStrategy":"validation","validationCode":"// Guard before begin():\nif connector.mocker.is_poisoned() { panic!(\"fixture corrupted by earlier panic; recreate MockDatabase\"); }","typeGuard":"fn can_begin(c: &MockDatabaseConnector) -> bool { !c.mocker.is_poisoned() }","tryCatchPattern":"std::panic::catch_unwind(AssertUnwindSafe(|| txn.begin()))\n    .unwrap_or_else(|_| recreate_mock_and_begin());","preventionTips":["Give every test its own MockDatabase instance","Make mock callbacks return errors instead of unwrapping on unexpected SQL","Capture and inspect the original panic before the cascade","Use serial test execution when sharing mock state"],"tags":["panic","mutex","mock","testing"],"backgroundTag":"mutex-lock-poisoned","analyzedSha":"e29bcd1b417c41a553b386fe94511d7c64a1c8ec","analyzedAt":"2026-09-10T11:31:52.468Z","contentChangedAt":"2026-09-10T11:31:52.468Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}