From 695b8a16b85b957ee5829c9514f642ee1b5524fa Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 21 Feb 2026 02:10:48 +0900 Subject: [PATCH] fix(ultrawork-db): wrap microtask/setTimeout callbacks in try/catch/finally Unhandled SQLite exceptions (SQLITE_BUSY, database locked, etc.) in queueMicrotask/setTimeout callbacks could crash the entire process. Added try/catch/finally to ensure db.close() is always called and errors are logged instead of crashing. --- src/plugin/ultrawork-db-model-override.ts | 58 +++++++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/plugin/ultrawork-db-model-override.ts b/src/plugin/ultrawork-db-model-override.ts index d8fade94..69d067e4 100644 --- a/src/plugin/ultrawork-db-model-override.ts +++ b/src/plugin/ultrawork-db-model-override.ts @@ -43,23 +43,61 @@ function retryViaMicrotask( attempt, }) setTimeout(() => { - if (tryUpdateMessageModel(db, messageId, targetModel, variant)) { - log(`[ultrawork-db-override] setTimeout fallback succeeded: ${targetModel.providerID}/${targetModel.modelID}`, { messageId }) - } else { - log("[ultrawork-db-override] setTimeout fallback failed - message not found", { messageId }) + try { + if (tryUpdateMessageModel(db, messageId, targetModel, variant)) { + log(`[ultrawork-db-override] setTimeout fallback succeeded: ${targetModel.providerID}/${targetModel.modelID}`, { messageId }) + } else { + log("[ultrawork-db-override] setTimeout fallback failed - message not found", { messageId }) + } + } catch (error) { + log("[ultrawork-db-override] setTimeout fallback failed with error", { + messageId, + error: String(error), + }) + } finally { + try { + db.close() + } catch (error) { + log("[ultrawork-db-override] Failed to close DB after setTimeout fallback", { + messageId, + error: String(error), + }) + } } - db.close() }, 0) return } queueMicrotask(() => { - if (tryUpdateMessageModel(db, messageId, targetModel, variant)) { - log(`[ultrawork-db-override] Deferred DB update (attempt ${attempt}): ${targetModel.providerID}/${targetModel.modelID}`, { messageId }) - db.close() - return + let shouldCloseDb = true + + try { + if (tryUpdateMessageModel(db, messageId, targetModel, variant)) { + log(`[ultrawork-db-override] Deferred DB update (attempt ${attempt}): ${targetModel.providerID}/${targetModel.modelID}`, { messageId }) + return + } + + shouldCloseDb = false + retryViaMicrotask(db, messageId, targetModel, variant, attempt + 1) + } catch (error) { + log("[ultrawork-db-override] Deferred DB update failed with error", { + messageId, + attempt, + error: String(error), + }) + } finally { + if (shouldCloseDb) { + try { + db.close() + } catch (error) { + log("[ultrawork-db-override] Failed to close DB after deferred DB update", { + messageId, + attempt, + error: String(error), + }) + } + } } - retryViaMicrotask(db, messageId, targetModel, variant, attempt + 1) }) }