{"record":{"id":"e620bbbab54f8417","repo":"SeaQL/sea-orm","slug":"fail-to-acquire-mocker-e620bb","errorCode":null,"errorMessage":"Fail to acquire mocker","messagePattern":"Fail to acquire mocker","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/driver/mock.rs","lineNumber":142,"sourceCode":"            execute_counter: AtomicUsize::new(0),\n            query_counter: AtomicUsize::new(0),\n            mocker: Mutex::new(Box::new(m)),\n        }\n    }\n\n    pub(crate) fn get_mocker_mutex(&self) -> &Mutex<Box<dyn MockDatabaseTrait>> {\n        &self.mocker\n    }\n\n    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [MockDatabase]\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.mocker\n            .lock()\n            .expect(\"Fail to acquire mocker\")\n            .get_database_backend()\n    }\n\n    /// Execute the SQL statement in the [MockDatabase]\n    #[instrument(level = \"trace\", skip(statement))]\n    pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.execute_counter.fetch_add(1, Ordering::SeqCst);\n        self.mocker\n            .lock()\n            .map_err(exec_err)?\n            .execute(counter, statement)\n    }\n\n    /// Return one [QueryResult] if the query was successful\n    #[instrument(level = \"trace\", skip(statement))]\n    pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/src/driver/mock.rs#L124-L160","documentation":"The MockDatabase connector calls .lock().expect(\"Fail to acquire mocker\") on a Mutex guarding the mocker. If another thread panicked while holding the lock, the mutex is poisoned and lock() returns Err, causing this panic. It indicates a poisoned-lock situation, not a logic error in your test code itself.","triggerScenarios":"Calling MockDatabaseConnector::get_database_backend() after any thread panicked while holding the mocker mutex (e.g. a panicked assert inside a mock callback).","commonSituations":"Parallel tests sharing one MockDatabase connector where one test panics mid-mock; a mock closure that unwraps on unexpected SQL, poisoning the lock for all subsequent calls.","solutions":["Fix the original panic that poisoned the lock — inspect the panic message from the first failing thread/test.","Give each test its own MockDatabase/connector instead of sharing one across threads.","Use lock().unwrap_or_else(|p| p.into_inner()) if you prefer to recover from poisoning rather than panic.","Avoid panicking assertions inside mock callbacks; return errors instead."],"exampleFix":"// before\nself.mocker.lock().expect(\"Fail to acquire mocker\").get_database_backend()\n// after\nself.mocker.lock().unwrap_or_else(|poisoned| poisoned.into_inner()).get_database_backend()","handlingStrategy":"validation","validationCode":"// Before using the shared mock connector, check the lock is not poisoned:\nassert!(!connector.mocker.is_poisoned(), \"mocker lock poisoned by an earlier panic\");","typeGuard":"fn mocker_healthy(c: &MockDatabaseConnector) -> bool { !c.mocker.is_poisoned() }","tryCatchPattern":"let backend = std::panic::catch_unwind(AssertUnwindSafe(|| connector.get_database_backend()))\n    .unwrap_or_else(|_| DbBackend::Postgres); // fallback for poisoned lock","preventionTips":["Never share one MockDatabase across parallel tests","Avoid panicking assertions inside mock callbacks","Run the first failing test serially to expose the poisoning panic","Check Mutex::is_poisoned in test teardown to detect root panics early"],"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"}