|
64 | 64 | await migrate(drizzle(client), { migrationsFolder: './migrations' }) |
65 | 65 | console.log('Migrations applied successfully.') |
66 | 66 | } finally { |
67 | | - try { |
68 | | - await client`SELECT pg_advisory_unlock(${MIGRATION_LOCK_KEY})` |
69 | | - } catch (unlockError) { |
70 | | - // A failed explicit unlock must never mask a successful migration with a |
71 | | - // non-zero exit — the session lock auto-releases on disconnect anyway, so |
72 | | - // log and move on rather than letting this reach the outer catch. |
73 | | - console.error( |
74 | | - 'WARN: pg_advisory_unlock failed; the session lock will auto-release on disconnect.', |
75 | | - unlockError |
76 | | - ) |
77 | | - } |
| 67 | + await releaseMigrationLock() |
78 | 68 | } |
79 | 69 | } catch (error) { |
80 | 70 | console.error('ERROR: Migration failed.') |
|
84 | 74 | await client.end() |
85 | 75 | } |
86 | 76 |
|
| 77 | +/** |
| 78 | + * Release the advisory lock without ever failing the process. The session-level |
| 79 | + * lock auto-releases when the connection closes, so a thrown unlock — e.g. the |
| 80 | + * connection dropped right after `migrate()` committed — must be swallowed. |
| 81 | + * Letting it reach the outer `catch` would exit 1 and falsely report a |
| 82 | + * successful migration as failed to the deploy orchestrator. |
| 83 | + */ |
| 84 | +async function releaseMigrationLock(): Promise<void> { |
| 85 | + try { |
| 86 | + await client`SELECT pg_advisory_unlock(${MIGRATION_LOCK_KEY})` |
| 87 | + } catch (unlockError) { |
| 88 | + console.error( |
| 89 | + 'WARN: pg_advisory_unlock failed; the session lock will auto-release on disconnect.', |
| 90 | + unlockError |
| 91 | + ) |
| 92 | + } |
| 93 | +} |
| 94 | + |
87 | 95 | /** |
88 | 96 | * Print every diagnostic field a Postgres driver puts on a thrown error. The default |
89 | 97 | * `error.message` loses the constraint name, affected table/column, PG code, and hint — |
|
0 commit comments