Zackriya-Solutions/meetily · error
DB error: {}
Error message
DB error: {} What it means
`pool.acquire()` failed before any SQL executed. sqlx surfaces two main kinds here: PoolTimedOut (every connection in the SQLite pool was checked out longer than acquire_timeout, default 30s) and PoolClosed (the pool was closed, typically during app shutdown while the import was still saving). The {} carries that underlying sqlx error.
Source
Thrown at frontend/src-tauri/src/audio/import.rs:700
progress_percentage: progress,
message: message.to_string(),
},
);
}
/// Create a new meeting with transcripts in the database
async fn create_meeting_with_transcripts(
pool: &sqlx::SqlitePool,
title: &str,
segments: &[TranscriptSegment],
folder_path: String,
) -> Result<String> {
let meeting_id = format!("meeting-{}", Uuid::new_v4());
let now = chrono::Utc::now();
// Start transaction
let mut conn = pool.acquire().await.map_err(|e| anyhow!("DB error: {}", e))?;
let mut tx = sqlx::Connection::begin(&mut *conn)
.await
.map_err(|e| anyhow!("Failed to start transaction: {}", e))?;
// Insert meeting
sqlx::query(
"INSERT INTO meetings (id, title, created_at, updated_at, folder_path)
VALUES (?, ?, ?, ?, ?)",
)
.bind(&meeting_id)
.bind(title)
.bind(now)
.bind(now)
.bind(&folder_path)
.execute(&mut *tx)
.await
.map_err(|e| anyhow!("Failed to create meeting: {}", e))?;
View on GitHub (pinned to 0281737d87)
Solutions
- Read the sqlx error kind in the {} — PoolTimedOut and PoolClosed have opposite fixes
- For PoolTimedOut: raise max_connections and acquire_timeout in the PoolOptions used by db_manager
- For PoolClosed: keep the import task alive until completion (await its handle before closing the pool at shutdown)
- Enable WAL journal and busy_timeout on connect so writers queue less
Example fix
// before
let mut conn = pool.acquire().await.map_err(|e| anyhow!("DB error: {}", e))?;
// after — retry transient pool exhaustion with backoff
let mut conn = loop {
match pool.acquire().await {
Ok(c) => break c,
Err(e) if retries < 3 && e.to_string().contains("timed out") => {
retries += 1;
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
}
Err(e) => return Err(anyhow!("DB error: {}", e)),
}
}; Defensive patterns
Strategy: retry
Validate before calling
// size the pool for concurrent DB users at startup
SqlitePoolOptions::new()
.max_connections(8)
.acquire_timeout(Duration::from_secs(60))
.connect(&db_url)
.await? Try / catch
Retry pool.acquire() up to 3 times with 500ms backoff when the sqlx error is a timeout; fail immediately on PoolClosed since retrying a closed pool never succeeds.
Prevention
- Raise max_connections/acquire_timeout if imports coincide with heavy DB features
- Await in-flight import tasks before closing the pool at app shutdown
- Watch for other processes locking the SQLite file (backup tools, second instance)
When it happens
Trigger: The import reaches the 'saving' stage (85%) while other long-running DB operations hold all pool connections; the app quits and closes the pool mid-import; or the SQLite file/directory becomes unreadable so new connections fail.
Common situations: Importing while a meeting summary or history query runs; many concurrent Tauri commands sharing a small pool; app exit before async tasks finish; DB file permissions changed by backup software.
Related errors
- Failed to start transaction: {}
- Failed to create meeting: {}
- Failed to insert transcript: {}
- Failed to commit transaction: {}
- DB error: {}
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/791f139d54f2fd6b.
Report an issue: GitHub.