{"record":{"id":"f13a34fc9f66fe1e","repo":"SeaQL/sea-orm","slug":"fail-to-acquire-mocker","errorCode":null,"errorMessage":"Fail to acquire mocker","messagePattern":"Fail to acquire mocker","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sea-orm-sync/src/database/db_connection.rs","lineNumber":549,"sourceCode":"    /// Panics if [DbConn] is not a mock connection.\n    pub fn as_mock_connection(&self) -> &crate::MockDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::MockDatabaseConnection(mock_conn) => mock_conn,\n            _ => panic!(\"Not mock connection\"),\n        }\n    }\n\n    /// Get the transaction log as a collection Vec<[crate::Transaction]>\n    ///\n    /// # Panics\n    ///\n    /// Panics if the mocker mutex is being held by another thread.\n    pub fn into_transaction_log(self) -> Vec<crate::Transaction> {\n        let mut mocker = self\n            .as_mock_connection()\n            .get_mocker_mutex()\n            .lock()\n            .expect(\"Fail to acquire mocker\");\n        mocker.drain_transaction_log()\n    }\n}\n\n#[cfg(feature = \"proxy\")]\nimpl DatabaseConnection {\n    /// Generate a database connection for testing the Proxy database\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a proxy connection.\n    pub fn as_proxy_connection(&self) -> &crate::ProxyDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::ProxyDatabaseConnection(proxy_conn) => proxy_conn,\n            _ => panic!(\"Not proxy connection\"),\n        }\n    }\n}","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/sea-orm-sync/src/database/db_connection.rs#L531-L567","documentation":"into_transaction_log drains the mock connection's transaction log under a std Mutex. If the mocker mutex cannot be locked (already held by another thread, or poisoned by a prior panic), .lock().expect(...) panics with 'Fail to acquire mocker'. The method's doc comment explicitly warns of this panic.","triggerScenarios":"Calling DatabaseConnection::into_transaction_log() on a mock connection while another thread holds the mocker mutex, or after a previous panic while holding the lock poisoned the mutex.","commonSituations":"Parallel tests sharing one MockDatabase connection; a test that panicked earlier while holding the lock, poisoning it for subsequent callers.","solutions":["Ensure only one thread calls into_transaction_log at a time (drain once per connection)","Fix the earlier panic that poisoned the mutex before draining the log","Recover from poisoning with poisoned.into_inner() if the log is still needed","Guard the mock connection with your own synchronization in tests"],"exampleFix":"// before\nlet log = db.into_transaction_log(); // panics if mutex held/poisoned\n// after\nlet mocker = db.as_mock_connection().get_mocker_mutex();\nlet log = { let m = mocker.lock().unwrap_or_else(|e| e.into_inner()); m.drain_transaction_log() };","handlingStrategy":"try-catch","validationCode":"fn can_drain(db: &DatabaseConnection) -> bool {\n    db.as_mock_connection().get_mocker_mutex().try_lock().is_ok()\n}","typeGuard":null,"tryCatchPattern":"// recover from poisoned lock instead of expect\nlet mocker = db.as_mock_connection().get_mocker_mutex();\nlet mut m = match mocker.lock() {\n    Ok(g) => g,\n    Err(poisoned) => poisoned.into_inner(), // recover after fixing the panicking thread\n};\nlet log = m.drain_transaction_log();","preventionTips":["Call into_transaction_log from a single thread per mock connection","Drain the log exactly once per connection","Investigate and fix any earlier panic that poisons the mutex","Serialize test access to shared mock databases"],"tags":["panic","mutex","concurrency","mock","testing"],"backgroundTag":"invalid-state-transition","analyzedSha":"e29bcd1b417c41a553b386fe94511d7c64a1c8ec","analyzedAt":"2026-09-10T11:31:52.468Z","contentChangedAt":"2026-09-10T11:31:52.468Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}