# 🧠 tranxpress

An elegant, extensible, and **fully TypeScript-supported** async handler utility for Express.js that simplifies error handling, supports **MongoDB transactions**, and allows **nested error handlers** for next-level control.

---

## 🚀 Features

- 🔁 Wrap async/await routes and middlewares without try-catch hell.
- 🧩 Optional MongoDB transactions using Mongoose sessions.
- 🔄 Nested `asyncHandler` support (yes, recursion like a boss).
- 🔍 Smart MongoDB error parsing with stack trace and error code support.
- 🛠️ Plug-in custom error handlers at any depth.
- ✅ Built-in TypeScript typings for safety and autocompletion bliss.
- 📦 Includes extendable `ErrorResponse` and `SuccessResponse` classes.

---

## 📦 Installation

```bash
npm install tranxpress
```

If you're using TypeScript and Express:

```bash
npm install --save-dev @types/express
```

---

## 🧑‍💻 Usage

### Basic Example

```ts
import express from "express";
import { asyncHandler } from "tranxpress";

const app = express();

app.get(
  "/ping",
  asyncHandler(async (req, res) => {
    // simulate async error
    throw new Error("Boom 💥");
  })
);
```

---

## 💼 With MongoDB Transaction (Mongoose)

```ts
app.post(
  "/create-user",
  asyncHandler(async (req, res) => {
    const session = req.session;
    const user = await User.create([{ name: "iBoon" }], { session });
    res.json({ user });
  }, { useTransaction: true })
);
```

> `req.session` is automatically injected if `useTransaction` is true.

---

## 🧬 Nested Error Handlers

You can define a hierarchy of error handlers using `asyncHandler` recursively.

```ts
const deepestHandler = asyncHandler(async (err, req, res) => {
  console.log("🔥 Deep nested handler:", err.message);
});

const middleHandler = asyncHandler(async (err, req, res) => {
  console.log("🧩 Middle layer handling error...");
  throw err; // pass to next handler
}, { customErrorHandler: deepestHandler });

app.get(
  "/crash",
  asyncHandler(async (req, res) => {
    throw new Error("Nested Boom 💣");
  }, { customErrorHandler: middleHandler })
);
```

---

## 📦 Advanced MongoDB Error Handling

The package includes a robust `MongoHandledError` wrapper class.

```ts
throw new MongoHandledError(originalMongoError);
```

It parses common errors like:

- `ValidationError` → 400
- `CastError` → 400
- `MongoServerError` → 500
- `DuplicateKeyError` (code `11000`) → 409

The error contains:

```ts
{
  message: "Duplicate key error",
  statusCode: 409,
  stack: "...",
  code: 11000
}
```

---

## 🧰 API Reference

### `asyncHandler(fn, options?)`

| Param                       | Type                        | Description                                 |
|----------------------------|-----------------------------|---------------------------------------------|
| `fn`                       | `(req, res, next) => {}`    | The async route/controller function         |
| `options.useTransaction`   | `boolean`                   | Enable MongoDB transaction (Mongoose)       |
| `options.customErrorHandler` | `AsyncFn`                 | Another asyncHandler or custom error logic  |

---

## ✅ Response Classes

### `ErrorResponse`

Use this to throw custom errors.

```ts
import { ErrorResponse } from "tranxpress";

throw new ErrorResponse("Invalid input", 400, { field: "email" });
```

You can extend it:

```ts
class CustomError extends ErrorResponse {
  constructor(message: string) {
    super(message, 422);
  }
}
```

### `SuccessResponse`

Use this for consistent success responses.

```ts
import { SuccessResponse } from "tranxpress";

res.status(200).json(new SuccessResponse("User created", { user }));
```

---

## 🔐 Error Object Structure

If the handler catches an error, it forwards:

```ts
{
  message: "Something went wrong",
  statusCode: 500
}
```

You can access more details if needed:

```ts
error.code
error.stack
error.reason
```

---

## 🧪 Testing It Out

You can test it with this setup:

```ts
app.use((err, req, res, next) => {
  res.status(err.statusCode || 500).json({
    error: err.message,
    stack: process.env.NODE_ENV === "development" ? err.stack : undefined
  });
});
```

---

## ⛳ Suggested Folder Structure

```
📦 src/
├── asyncHandler.ts
├── utils/
│   └── mongoErrorHandler.ts
├── responses/
│   ├── ErrorResponse.ts
│   └── SuccessResponse.ts
├── types/
│   └── sharedTypes.ts
```

---

## 🔑 Keywords

```
express, middleware, async handler, async middleware, typescript, error handler, mongoose, transaction, mongodb, nested error handler, api wrapper, clean error handling, success response, error response
```

---

## 🧠 Future Ideas

- 🌍 Localization support for user-friendly error messages.
- 🚧 Limit recursion depth for nested handlers.
- 🧪 Built-in test utils (mocking sessions, errors, etc).

---

## 🧑‍🎓 Author

Made with ❤️ by [iBoon Technologies].

---

Ready to handle errors like a pro?  
Use `tranxpress` and say goodbye to callback hell forever. 😎