Skip to content

ashkansamadiyan/rusty-ts-err

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Rust-Style Error Handling for TypeScript

A robust, type-safe error handling library for TypeScript that closely mirrors Rust's error handling patterns. This library helps you write more reliable code by making error handling explicit and leveraging TypeScript's type system to catch errors at compile time.

Features

  • πŸ¦€ Rust-like Result<T, E> type for explicit error handling
  • πŸ”’ Type-safe validation types for common use cases
  • ⚑ Full async support with ResultAsync<T, E>
  • πŸ›‘οΈ Comprehensive error type system
  • 🚨 Panic system for unrecoverable errors
  • πŸ“ Extensive documentation and examples

Installation

# Using bun
bun add rust-errors

# Using npm
npm install rust-errors

# Using yarn
yarn add rust-errors

Basic Usage

Result Type

import { type Result, ok, err, match } from 'rust-errors';

function divide(a: number, b: number): Result<number, string> {
  if (b === 0) {
    return err('Division by zero');
  }
  return ok(a / b);
}

// Using pattern matching
match(
  divide(10, 2),
  (value) => console.log('Result:', value),
  (error) => console.error('Error:', error),
);

// Using unwrap (throws if error)
try {
  const result = divide(10, 0).unwrap();
  console.log('Result:', result);
} catch (e) {
  console.error('Error:', e);
}

Validation Types

import {
  type Result,
  NonEmptyString,
  EmailAddress,
  RangeNumber,
  ValidationError,
} from 'rust-errors';

// Validate a non-empty string
const name = NonEmptyString.create('John Doe');
if (name.isOk()) {
  console.log('Valid name:', name.unwrap().toString());
}

// Validate an email address
const email = EmailAddress.create('invalid-email');
if (email.isErr()) {
  console.error('Invalid email:', email.err()?.message);
}

// Validate a number in range
const age = RangeNumber.create(25, 0, 120);
if (age.isOk()) {
  console.log('Valid age:', age.unwrap().valueOf());
}

Async Support

import {
  type ResultAsync,
  toResultAsync,
  NetworkError,
  andThenAsync,
} from 'rust-errors';

async function fetchUser(id: number): ResultAsync<User, NetworkError> {
  return toResultAsync(
    fetch(`/api/users/${id}`).then((res) => res.json()),
    (error) => new NetworkError('Failed to fetch user', error),
  );
}

// Chain async operations
const userAndPosts = await andThenAsync(
  fetchUser(1),
  async (user) => fetchUserPosts(user.id),
);

if (userAndPosts.isOk()) {
  const posts = userAndPosts.unwrap();
  console.log('User posts:', posts);
}

Custom Validation Types

import { type Result, ok, err, ValidationError } from 'rust-errors';

class PostalCode {
  private constructor(private readonly value: string) {}

  static create(value: string): Result<PostalCode, ValidationError> {
    const pattern = /^\d{5}(-\d{4})?$/;
    if (!pattern.test(value)) {
      return err(new ValidationError('Invalid postal code format'));
    }
    return ok(new PostalCode(value));
  }

  toString(): string {
    return this.value;
  }
}

const postalCode = PostalCode.create('12345-6789');
if (postalCode.isOk()) {
  console.log('Valid postal code:', postalCode.unwrap().toString());
}

Error Types

import {
  NetworkError,
  ValidationError,
  TimeoutError,
  ParseError,
} from 'rust-errors';

// Network error with status code
const networkError = new NetworkError('API request failed', 404);

// Validation error with cause
const validationError = new ValidationError(
  'Invalid input',
  new Error('Value out of range'),
);

// Timeout error with duration
const timeoutError = new TimeoutError('Operation timed out', 5000);

// Parse error
const parseError = new ParseError('Failed to parse JSON');

Panic System

import { panic, assert, unreachable, configurePanic } from 'rust-errors';

// Configure panic behavior
configurePanic({
  includeStackTrace: true,
  handler: (message, error) => {
    console.error('Fatal error:', message);
    process.exit(1);
  },
});

// Assert conditions
function sqrt(n: number): number {
  assert(n >= 0, 'Number must be non-negative');
  return Math.sqrt(n);
}

// Mark unreachable code
function processValue(value: 'A' | 'B'): string {
  switch (value) {
    case 'A':
      return 'Value is A';
    case 'B':
      return 'Value is B';
    default:
      return unreachable('All cases should be handled');
  }
}

Examples

Check out the examples directory for more detailed examples:

API Documentation

For detailed API documentation, see the API docs.

Contributing

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published