mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: handle migration race condition in concurrent test workers
Drizzle's migrate() throws when multiple vitest workers race to apply
migrations on the same temp database. The DrizzleError wraps a
SqliteError ("table already exists") in its cause chain. Add a
same-process guard and a catch that checks both the outer message and
cause for "already exists" so the second worker continues safely.
This commit is contained in:
@@ -9,6 +9,34 @@ const __dirname = dirname(__filename);
|
|||||||
// Resolve migrations folder relative to this file, not the working directory
|
// Resolve migrations folder relative to this file, not the working directory
|
||||||
const migrationsFolder = join(__dirname, "../../drizzle");
|
const migrationsFolder = join(__dirname, "../../drizzle");
|
||||||
|
|
||||||
|
function isAlreadyExistsError(err: unknown): boolean {
|
||||||
|
if (err instanceof Error) {
|
||||||
|
if (err.message.includes("already exists")) return true;
|
||||||
|
// DrizzleError wraps the real SqliteError in .cause
|
||||||
|
if ("cause" in err && err.cause instanceof Error) {
|
||||||
|
return err.cause.message.includes("already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let migrated = false;
|
||||||
|
|
||||||
export function runMigrations() {
|
export function runMigrations() {
|
||||||
migrate(db, { migrationsFolder });
|
if (migrated) return;
|
||||||
|
try {
|
||||||
|
migrate(db, { migrationsFolder });
|
||||||
|
} catch (err: unknown) {
|
||||||
|
// In test / multi-process environments, concurrent workers may race to
|
||||||
|
// apply migrations on the same database file. If a table already exists,
|
||||||
|
// the schema is in place and we can safely continue.
|
||||||
|
// Drizzle wraps the SqliteError in a DrizzleError, so check both the
|
||||||
|
// outer message and the cause chain.
|
||||||
|
if (isAlreadyExistsError(err)) {
|
||||||
|
// Tables created by another process — DB is ready
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user