Skip to content

Commit

Permalink
Forward success results in runTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
emlun committed Feb 14, 2024
1 parent cc8ea2d commit 1b468b3
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
16 changes: 11 additions & 5 deletions src/entities/common.entity.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Result } from "ts-results";
import { EntityManager } from "typeorm"

import AppDataSource from "../AppDataSource";
Expand All @@ -10,15 +11,20 @@ import AppDataSource from "../AppDataSource";
*
* This function accepts `Err` `Result`s to signal that the transaction should
* be aborted, in addition to the conventional signals of throwing an exception
* or returning a rejected `Promise`.
* or returning a rejected `Promise`. `Ok<T>` results are unpacked to return
* just the contained `T` type.
*/
export async function runTransaction<T>(runInTransaction: (entityManager: EntityManager) => Promise<T>): Promise<T> {
export async function runTransaction<T, E>(runInTransaction: (entityManager: EntityManager) => Promise<Result<T, E> | T>): Promise<T> {
return await AppDataSource.manager.transaction(async (entityManager) => {
const result = await runInTransaction(entityManager);
if ("err" in result && "val" in result) {
if (result["err"]) {
return Promise.reject(result["val"]);
if ("val" in result && "ok" in result && "err" in result) {
if (result.ok) {
return Promise.resolve(result.val);
} else {
return Promise.reject(result.val);
}
} else {
return result;
}
});
}
8 changes: 2 additions & 6 deletions src/routers/user.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ userController.post('/webauthn/credential/:id/delete', async (req: Request, res:
userController.delete('/', async (req: Request, res: Response) => {
const userDID = req.user.did;
try {
const result = await runTransaction(async (entityManager: EntityManager) => {
await runTransaction(async (entityManager: EntityManager) => {
// Note: this executes all four branches before checking if any failed.
// ts-results does not seem to provide an async-optimized version of Result.all(),
// and it turned out nontrivial to write one that preserves the Ok and Err types like Result.all() does.
Expand All @@ -484,11 +484,7 @@ userController.delete('/', async (req: Request, res: Response) => {
);
});

if (result.err) {
return res.status(400).send({ result: result.val })
} else {
return res.send({ result: "DELETED" });
}
return res.send({ result: "DELETED" });
} catch (e) {
return res.status(400).send({ result: e })
}
Expand Down

0 comments on commit 1b468b3

Please sign in to comment.