Skip to content

Commit 729bb18

Browse files
committed
Allow EdgeDB to retry exceptions wrapped in retryable EdgeDB exceptions
This is the same thing we do with neo4j as well.
1 parent 8c66d4f commit 729bb18

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/core/edgedb/transaction.context.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Injectable, OnModuleDestroy } from '@nestjs/common';
22
import { AsyncLocalStorage } from 'async_hooks';
3-
import { Executor } from 'edgedb';
3+
import { EdgeDBError, Executor } from 'edgedb';
4+
import { getPreviousList } from '~/common';
45
import { Client } from './reexports';
56

67
@Injectable()
@@ -13,9 +14,31 @@ export class TransactionContext
1314
}
1415

1516
async inTx<R>(fn: () => Promise<R>): Promise<R> {
16-
return await this.client.transaction(async (tx) => {
17-
return await this.run(tx, fn);
18-
});
17+
const errorMap = new WeakMap<Error, Error>();
18+
19+
try {
20+
return await this.client.transaction(async (tx) => {
21+
try {
22+
return await this.run(tx, fn);
23+
} catch (error) {
24+
// If the error "wraps" an EdgeDB error, then
25+
// throw that here and save the original.
26+
// This allows EdgeDB to check if the error is retry-able.
27+
// If it is, then this error doesn't matter; otherwise we'll unwrap below.
28+
const maybeRetryableError = getPreviousList(error, true).find(
29+
(e) => e instanceof EdgeDBError,
30+
);
31+
if (maybeRetryableError) {
32+
errorMap.set(maybeRetryableError, error);
33+
throw maybeRetryableError;
34+
}
35+
throw error;
36+
}
37+
});
38+
} catch (error) {
39+
// Unwrap the original error if it was wrapped above.
40+
throw errorMap.get(error) ?? error;
41+
}
1942
}
2043

2144
get current() {

0 commit comments

Comments
 (0)