SeaQL/sea-orm · error
Fail to acquire mocker
Error message
Fail to acquire mocker
What it means
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.
Source
Thrown at sea-orm-sync/src/database/db_connection.rs:549
/// Panics if [DbConn] is not a mock connection.
pub fn as_mock_connection(&self) -> &crate::MockDatabaseConnection {
match &self.inner {
DatabaseConnectionType::MockDatabaseConnection(mock_conn) => mock_conn,
_ => panic!("Not mock connection"),
}
}
/// Get the transaction log as a collection Vec<[crate::Transaction]>
///
/// # Panics
///
/// Panics if the mocker mutex is being held by another thread.
pub fn into_transaction_log(self) -> Vec<crate::Transaction> {
let mut mocker = self
.as_mock_connection()
.get_mocker_mutex()
.lock()
.expect("Fail to acquire mocker");
mocker.drain_transaction_log()
}
}
#[cfg(feature = "proxy")]
impl DatabaseConnection {
/// Generate a database connection for testing the Proxy database
///
/// # Panics
///
/// Panics if [DbConn] is not a proxy connection.
pub fn as_proxy_connection(&self) -> &crate::ProxyDatabaseConnection {
match &self.inner {
DatabaseConnectionType::ProxyDatabaseConnection(proxy_conn) => proxy_conn,
_ => panic!("Not proxy connection"),
}
}
}View on GitHub (pinned to e29bcd1b41)
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
Example fix
// before
let log = db.into_transaction_log(); // panics if mutex held/poisoned
// after
let mocker = db.as_mock_connection().get_mocker_mutex();
let log = { let m = mocker.lock().unwrap_or_else(|e| e.into_inner()); m.drain_transaction_log() }; Defensive patterns
Strategy: try-catch
Validate before calling
fn can_drain(db: &DatabaseConnection) -> bool {
db.as_mock_connection().get_mocker_mutex().try_lock().is_ok()
} Try / catch
// recover from poisoned lock instead of expect
let mocker = db.as_mock_connection().get_mocker_mutex();
let mut m = match mocker.lock() {
Ok(g) => g,
Err(poisoned) => poisoned.into_inner(), // recover after fixing the panicking thread
};
let log = m.drain_transaction_log(); Prevention
- 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
When it happens
Trigger: 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.
Common situations: Parallel tests sharing one MockDatabase connection; a test that panicked earlier while holding the lock, poisoning it for subsequent callers.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Fail to acquire mocker
- Fail to acquire mocker
- Failed to acquire mocker
- Not mock connection
- There is no open transaction to commit
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/f13a34fc9f66fe1e.
Report an issue: GitHub.