An open API service indexing awesome lists of open source software.

https://github.com/marian1309/try-catch

🔒 Type-safe try/catch wrapper ⚙️ for async operations ⚡️
https://github.com/marian1309/try-catch

error-handling try-catch typescript

Last synced: 12 months ago
JSON representation

🔒 Type-safe try/catch wrapper ⚙️ for async operations ⚡️

Awesome Lists containing this project

README

          

# `@pidchashyi/try-catch`

> 🧰 Type-safe `try/catch` wrapper for async operations — returns structured `Result` objects instead of throwing errors.

Eliminate unhandled exceptions and simplify async error handling with a clean, typed interface. Features optional logging, lifecycle hooks, retry mechanisms, performance tracking, and full type inference.

---

## 📦 Installation

```bash
npm install @pidchashyi/try-catch
```

---

## ⚙️ Core Types

### `Result`

```ts
type Result = Success | Failure;
```

#### Success Type

```ts
type Success = {
status: "success"; // Always "success"
data: T; // The successful result data
error: null; // Always null
performance?: number; // Execution time in seconds (if enabled)
};
```

#### Failure Type

```ts
type Failure = {
status: "failure"; // Always "failure"
data: null; // Always null
error: E; // The error that occurred
performance?: number; // Execution time in seconds (if enabled)
};
```

### Configuration Types

#### RetryOptions

```ts
type RetryOptions = {
retries: number; // Number of retry attempts
delayMs?: number; // Delay between retries in milliseconds
};
```

#### BaseTryCatchOptions

```ts
type BaseTryCatchOptions = {
logError?: boolean; // Enable error logging to console
onError?: (error: E) => void; // Custom error handler callback
onFinally?: () => void; // Callback executed after try-catch
performance?: boolean; // Enable performance tracking in seconds
};
```

#### TryCatchOptions

```ts
type TryCatchOptions = BaseTryCatchOptions & {
retry?: RetryOptions;
};
```

#### TryCatchAllOptions

```ts
type TryCatchAllOptions = BaseTryCatchOptions & {
failFast?: boolean; // If true, fails on first error (default)
};
```

#### PartialResults

```ts
type PartialResults = {
successes: T[]; // Array of successful results
errors: E[]; // Array of errors that occurred
successIndices: number[]; // Original indices of successes
errorIndices: number[]; // Original indices of failures
};
```

---

## 🌍 Global Configuration

The package provides utilities to set global configuration options that will be applied to all try-catch operations. Local options passed to individual try-catch calls will override these global settings.

### Global Configuration Functions

```ts
setGlobalTryCatchConfig(config: Partial): void
getGlobalTryCatchConfig(): Partial
```

### Example: Setting Global Error Handling

```ts
// @/app/layout.tsx
import { setGlobalTryCatchConfig } from "@pidchashyi/try-catch";

// Set up global error tracking for all try-catch operations
setGlobalTryCatchConfig({
logError: true,
performance: true,
onError: async (error) => {
await trackError({
message: "Unhandled tryCatch error",
source: "global",
error,
});
},
});

// All subsequent try-catch calls will use these settings
const result1 = await tryCatch(fetchData()); // Uses global config
const result2 = await tryCatchSync(processData); // Uses global config

// Local options override global settings
const result3 = await tryCatch(fetchData(), {
logError: false, // Overrides global logError setting
onError: (err) => customErrorHandler(err), // Overrides global onError handler
});
```

### Available Global Options

The global configuration accepts all standard try-catch options:

```ts
type TryCatchOptions = {
logError?: boolean; // Enable error logging to console
onError?: (error: E) => void; // Global error handler
onFinally?: () => void; // Global cleanup function
performance?: boolean; // Enable performance tracking
retry?: {
// Global retry settings
retries: number;
delayMs?: number;
};
};
```

### Best Practices

- Set global configuration early in your application's lifecycle
- Use global config for common error tracking/logging
- Override global settings with local options when needed
- Keep global handlers lightweight to avoid performance impact
- Consider using TypeScript for better type inference

---

## 🛠️ Core Functions

### `tryCatchSync`

Synchronous try-catch wrapper for non-async operations.

```ts
const result = tryCatchSync(() => someOperation(), {
select: (data) => transformData(data),
logError: true,
onError: (err) => handleError(err),
onFinally: () => cleanup(),
});
```

### `tryCatch`

Asynchronous try-catch wrapper with retry capabilities.

```ts
const result = await tryCatch(fetchData(), {
retry: { retries: 3, delayMs: 1000 },
select: (data) => transformData(data),
logError: true,
onError: (err) => handleError(err),
onFinally: () => cleanup(),
});
```

### `tryCatchAll`

Execute multiple promises concurrently with fail-fast behavior.

```ts
const result = await tryCatchAll([promise1, promise2, promise3], {
logError: true,
onError: (err) => handleError(err),
onFinally: () => cleanup(),
});
```

### `tryCatchAllSafe`

Execute multiple promises concurrently with fail-soft behavior.

```ts
const result = await tryCatchAllSafe([promise1, promise2, promise3], {
logError: true,
onError: (err) => handleError(err),
onFinally: () => cleanup(),
});
```

---

## 🔍 Utility Functions

### Type Guards

```ts
isSuccess(result: Result): result is Success
isFailure(result: Result): result is Failure
```

### Helper Functions

```ts
sleep(ms: number): Promise // Delay execution
toError(error: unknown): Error // Convert unknown to Error
getErrorMessage(error: unknown): string // Extract error message
map(result: Result, fn: (value: T) => U): Result // Transform success value
```

---

## 📝 Examples

### Basic Usage with Performance Tracking

```ts
import { tryCatch, isSuccess } from "@pidchashyi/try-catch";

const result = await tryCatch(
fetch("https://api.example.com/data").then((res) => res.json()),
{
select: (data) => data.items,
logError: true,
performance: true, // Enable performance tracking
}
);

if (isSuccess(result)) {
console.log("Data:", result.data);
console.log("Operation took:", result.performance, "seconds");
} else {
console.error("Error:", result.error);
console.log("Failed operation took:", result.performance, "seconds");
}
```

### With Retry Logic and Performance Tracking

```ts
const result = await tryCatch(fetchWithPotentialFailure(), {
retry: {
retries: 3,
delayMs: 1000,
},
logError: true,
onError: (err) => notifyUser(err),
performance: true, // Enable performance tracking
});

if (isSuccess(result)) {
console.log(`Operation succeeded in ${result.performance} seconds`);
}
```

### Parallel Operations

```ts
const result = await tryCatchAll([fetchUser(1), fetchUser(2), fetchUser(3)]);

if (isSuccess(result)) {
console.log("All users:", result.data);
}
```

### Safe Parallel Operations

```ts
const result = await tryCatchAllSafe([
fetchUser(1),
fetchUser(2),
fetchUser(3),
]);

if (isSuccess(result)) {
console.log("Successful fetches:", result.data.successes);
console.log("Failed fetches:", result.data.errors);
console.log("Success indices:", result.data.successIndices);
}
```

---

## 🛡️ Features & Benefits

✅ Fully typed `Success` / `Failure` results
✅ Comprehensive retry mechanism
✅ Performance tracking
✅ Parallel execution support
✅ Safe error handling with type inference
✅ Optional logging and lifecycle hooks
✅ Transform results with selectors
✅ No dependencies
✅ Framework agnostic

---

## 👤 Author

Built with safety-first philosophy by [Pidchashyi](https://github.com/Marian1309/try-catch)

---

## 📄 License

MIT © [LICENSE](https://github.com/Marian1309/try-catch/blob/main/LICENSE)