tranxpress
Version:
A smart async wrapper for Express with MongoDB transaction support.
63 lines (62 loc) • 2.41 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.asyncHandler = void 0;
const mongoose_1 = __importDefault(require("mongoose"));
const mongoErrorHandler_1 = require("../utils/mongoErrorHandler");
const asyncHandler = (fn, options = {}) => {
const { useTransaction = false, customErrorHandler } = options;
return async (req, res, next) => {
let session = null;
try {
if (useTransaction) {
session = await mongoose_1.default.startSession();
session.startTransaction();
req.session = session;
}
await fn(req, res, next);
if (session) {
await session.commitTransaction();
session.endSession();
}
}
catch (error) {
console.error("❌ Error caught in asyncHandler:", error);
if (session) {
try {
await session.abortTransaction();
session.endSession();
}
catch (abortErr) {
console.error("⚠️ Failed to abort transaction:", abortErr);
}
}
// Wrap known MongoDB errors
if (error.name === "MongoServerError" ||
error.name === "MongoError" ||
error.name === "CastError" ||
error.name === "ValidationError") {
error = new mongoErrorHandler_1.MongoHandledError(error);
}
// 🔁 Support nested asyncHandlers
if (typeof customErrorHandler === "function") {
try {
const result = customErrorHandler(error, req, res, next);
if (result instanceof Promise) {
await result;
}
}
catch (customHandlerError) {
console.error("⚠️ Error inside customErrorHandler:", customHandlerError);
}
}
return next({
message: error?.message || "Internal Server Error",
statusCode: error?.statusCode || 500,
});
}
};
};
exports.asyncHandler = asyncHandler;