JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 8
  • Score
    100M100P100Q61047F
  • License MIT

A TypeScript utility package for elegant error handling with Result types

Package Exports

  • @pidchashyi/try-catch
  • @pidchashyi/try-catch/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@pidchashyi/try-catch) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@pidchashyi/try-catch

🧰 Type-safe try/catch wrapper for async operations — returns structured Result<T, E> 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

npm install @pidchashyi/try-catch

⚙️ Core Types

Result<T, E>

type Result<T, E = Error> = Success<T> | Failure<E>;

Success Type

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

Failure Type

type Failure<E> = {
  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

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

BaseTryCatchOptions

type BaseTryCatchOptions<E = Error> = {
  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

type TryCatchOptions<E = Error> = BaseTryCatchOptions<E> & {
  retry?: RetryOptions;
};

TryCatchAllOptions

type TryCatchAllOptions<E = Error> = BaseTryCatchOptions<E> & {
  failFast?: boolean; // If true, fails on first error (default)
};

PartialResults

type PartialResults<T, E = Error> = {
  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

setGlobalTryCatchConfig(config: Partial<TryCatchOptions>): void
getGlobalTryCatchConfig(): Partial<TryCatchOptions>

Example: Setting Global Error Handling

// @/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:

type TryCatchOptions<E = Error> = {
  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<T, S = T, E = Error>

Synchronous try-catch wrapper for non-async operations.

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

tryCatch<T, S = T, E = Error>

Asynchronous try-catch wrapper with retry capabilities.

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

tryCatchAll<T, E = Error>

Execute multiple promises concurrently with fail-fast behavior.

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

tryCatchAllSafe<T, E = Error>

Execute multiple promises concurrently with fail-soft behavior.

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

🔍 Utility Functions

Type Guards

isSuccess<T, E>(result: Result<T, E>): result is Success<T>
isFailure<T, E>(result: Result<T, E>): result is Failure<E>

Helper Functions

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

📝 Examples

Basic Usage with Performance Tracking

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

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

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

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

Safe Parallel Operations

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<T> / Failure<E> 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


📄 License

MIT © LICENSE