Mirror of https://github.com/roostorg/coop
github.com/roostorg/coop
1import { type Kysely } from 'kysely';
2
3import { safeGet } from './misc.js';
4
5function isSerializationFailure(error: unknown): boolean {
6 return safeGet(error, ['code']) === '40001';
7}
8
9/**
10 * Like {@link server/models/sequelizeSetup.ts maketransactionWithRetry} but for Kysely.
11 */
12export function makeKyselyTransactionWithRetry<T>(kysely: Kysely<T>) {
13 return async function transactionWithRetry<R>(
14 callback: (trx: Kysely<T>) => Promise<R>,
15 ): Promise<R> {
16 let remainingTries = 3;
17 let lastError: unknown;
18 while (remainingTries > 0) {
19 remainingTries -= 1;
20 try {
21 return await kysely.transaction().execute(callback);
22 } catch (e: unknown) {
23 if (!isSerializationFailure(e)) {
24 throw e;
25 }
26 lastError = e;
27 }
28 }
29
30 throw lastError;
31 };
32}
33
34export type KyselyTransactionWithRetry<T> = ReturnType<
35 typeof makeKyselyTransactionWithRetry<T>
36>;