/**
* Run an `Effect` inside a Drizzle transaction, keeping the caller’s
* env / fiber-locals and mapping unexpected driver exceptions
*/
export const withDbTx2 = <Out, Err, Env>({
context,
run,
// isolationLevel?: "read committed" | "repeatable read" | "serializable" // optional if you later want it
}: {
context: string;
run: (tx: SpherePgDatabase) => Effect.Effect<Out, Err, Env>;
}) =>
Effect.gen(function* () {
// Run the tx on the caller's runtime so FiberRefs/env propagate
const rt = yield* Effect.runtime<Env>();
const db = yield* Database;
return yield* Effect.tryPromise({
try: () =>
db.transaction(async (tx) => {
// Drive the user program on the captured runtime
// Rejects on exceptions
const either = await Runtime.runPromise(rt, Effect.either(run(tx)));
// Right -> commit with value; Left -> abort with the domain error
return Either.isRight(either)
? either.right
: Promise.reject(either.left); // THIS ERROR SHOULD BE PASSED UP AS AN EFFECT ERROR
}),
catch: (cause) => classifyPgError(cause),
}).pipe(
Effect.retry(retryPolicy),
Effect.withSpan(`infra::postgres::withDbTx/${context}`)
);
});
/**
* Run an `Effect` inside a Drizzle transaction, keeping the caller’s
* env / fiber-locals and mapping unexpected driver exceptions
*/
export const withDbTx2 = <Out, Err, Env>({
context,
run,
// isolationLevel?: "read committed" | "repeatable read" | "serializable" // optional if you later want it
}: {
context: string;
run: (tx: SpherePgDatabase) => Effect.Effect<Out, Err, Env>;
}) =>
Effect.gen(function* () {
// Run the tx on the caller's runtime so FiberRefs/env propagate
const rt = yield* Effect.runtime<Env>();
const db = yield* Database;
return yield* Effect.tryPromise({
try: () =>
db.transaction(async (tx) => {
// Drive the user program on the captured runtime
// Rejects on exceptions
const either = await Runtime.runPromise(rt, Effect.either(run(tx)));
// Right -> commit with value; Left -> abort with the domain error
return Either.isRight(either)
? either.right
: Promise.reject(either.left); // THIS ERROR SHOULD BE PASSED UP AS AN EFFECT ERROR
}),
catch: (cause) => classifyPgError(cause),
}).pipe(
Effect.retry(retryPolicy),
Effect.withSpan(`infra::postgres::withDbTx/${context}`)
);
});