Skip to content

AhmedOsman101/lib-result

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

232 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lib-result

A Rust-inspired Result type for type-safe error handling in TypeScript and JavaScript.

Installation

npm install lib-result

Usage

TypeScript

import {
  Err,
  ErrFromObject,
  ErrFromText,
  ErrFromUnknown,
  Ok,
  type Result,
  wrap,
  wrapAsync,
} from "lib-result";

class DivisionError extends Error {}

function divide(a: number, b: number): Result<number, DivisionError> {
  if (b === 0) {
    return Err(new DivisionError("Cannot Divide By Zero"));
  }
  return Ok(a / b);
}

// Method-based API
const result = divide(6, 2);
if (result.isOk()) {
  console.log(result.ok); // 3
} else {
  console.error(result.error.message);
}

const mayDivide = divide(1, 0);
if (mayDivide.isError()) {
  console.error(mayDivide.error.message); // "Cannot Divide By Zero"
}

// Using unwrap
const errorResult = ErrFromText("Failed");
try {
  const value = errorResult.unwrap();
  console.log(value);
} catch (e) {
  console.error(e.message); // "Failed"
}

// Using expect for custom error messages
try {
  errorResult.expect("Failed to get user");
} catch (e: any) {
  console.error(e.message); // "Failed to get user"
  console.error(e.cause.message); // "Failed"
}

// Using unwrapOr for safe fallbacks
const safeValue = errorResult.unwrapOr(0); // 0

// Using wrap for synchronous operations
const wrappedResult = wrap(() => divide(10, 2));
if (wrappedResult.isOk()) {
  console.log(wrappedResult.ok); // 5
}

// Using wrapAsync for asynchronous operations
const asyncResult = await wrapAsync(() =>
  fetch("https://jsonplaceholder.typicode.com/users/1")
);
if (asyncResult.isOk()) {
  console.log(asyncResult.ok.status); // 200
}

// Using map and andThen for chaining transformations
const chained = divide(10, 2)
  .map(x => x + 1) // Ok(6)
  .andThen(x => divide(x, 2)); // Ok(3)
if (chained.isOk()) {
  console.log(chained.ok); // 3
}

// Using unwrapOrElse for computed fallback values
const fallback = errorResult.unwrapOrElse(error => error.message.length);

// Using Rust-style orElse for Result-to-Result recovery
const recovered = divide(1, 0).orElse(() => Ok(0));
if (recovered.isOk()) {
  console.log(recovered.ok); // 0
}

// Using match for pattern matching
const message = result.match({
  okFn: value => `Success: ${value}`,
  errFn: error => `Error: ${error.message}`,
});
console.log(message); // "Success: 3"

// Using ErrFromUnknown for catch blocks
function parseJson(json: string) {
  try {
    return Ok(JSON.parse(json));
  } catch (error) {
    return ErrFromUnknown(error);
  }
}

// Using ErrFromObject to create an error with custom properties
const customErr = ErrFromObject<number, { code: number; info: string }>({
  message: "Something went wrong",
  code: 123,
  info: "Custom",
});
if (customErr.isError()) {
  console.error(customErr.error.message); // "Something went wrong"
  console.error(customErr.error.code); // 123
  console.error(customErr.error.info); // "Custom"
}

JavaScript

import {
  Err,
  ErrFromObject,
  ErrFromText,
  ErrFromUnknown,
  Ok,
  wrap,
  wrapAsync,
} from "lib-result";

class DivisionError extends Error {}

function divide(a, b) {
  if (b === 0) {
    return Err(new DivisionError("Cannot Divide By Zero"));
  }
  return Ok(a / b);
}

// Method-based API
const result = divide(6, 2);
if (result.isOk()) {
  console.log(result.ok); // 3
} else {
  console.error(result.error.message);
}

const mayDivide = divide(1, 0);
if (mayDivide.isError()) {
  console.error(mayDivide.error.message); // "Cannot Divide By Zero"
}

// Using unwrap
const errorResult = ErrFromText("Failed");
try {
  const value = errorResult.unwrap();
  console.log(value);
} catch (e) {
  console.error(e.message); // "Failed"
}

// Using expect for custom error messages
try {
  errorResult.expect("Failed to get user");
} catch (e) {
  console.error(e.message); // "Failed to get user"
  console.error(e.cause.message); // "Failed"
}

// Using unwrapOr for safe fallbacks
const safeValue = errorResult.unwrapOr(0); // 0

// Using wrap for synchronous operations
const wrappedResult = wrap(() => divide(10, 2));
if (wrappedResult.isOk()) {
  console.log(wrappedResult.ok); // 5
}

// Using wrapAsync for asynchronous operations
const asyncResult = await wrapAsync(() =>
  fetch("https://jsonplaceholder.typicode.com/users/1")
);
if (asyncResult.isOk()) {
  console.log(asyncResult.ok.status); // 200
}

// Using map and andThen for chaining transformations
const chained = divide(10, 2)
  .map(x => x + 1) // Ok(6)
  .andThen(x => divide(x, 2)); // Ok(3)
if (chained.isOk()) {
  console.log(chained.ok); // 3
}

// Using unwrapOrElse for computed fallback values
const fallback = errorResult.unwrapOrElse(error => error.message.length);

// Using Rust-style orElse for Result-to-Result recovery
const recovered = divide(1, 0).orElse(() => Ok(0));
if (recovered.isOk()) {
  console.log(recovered.ok); // 0
}

// Using match for pattern matching
const message = result.match({
  okFn: value => `Success: ${value}`,
  errFn: error => `Error: ${error.message}`,
});
console.log(message); // "Success: 3"

// Using ErrFromUnknown for catch blocks
function parseJson(json) {
  try {
    return Ok(JSON.parse(json));
  } catch (error) {
    return ErrFromUnknown(error);
  }
}

// Using ErrFromObject to create an error with custom properties
const customErr = ErrFromObject({
  message: "Something went wrong",
  code: 123,
  info: "Custom",
});
if (customErr.isError()) {
  console.error(customErr.error.message); // "Something went wrong"
  console.error(customErr.error.code); // 123
  console.error(customErr.error.info); // "Custom"
}

Note

To check out the full documentation, API details, and advanced usage See the lib-result Wiki for comprehensive guides, API docs, and examples. The wiki is the main source for up-to-date documentation.

Source Code

You can view the full codebase, contribute, or report issues at the following repository: AhmedOsman101/lib-result Feel free to open issues for bugs or feature requests, or submit pull requests to improve the package!

About

A Rust-inspired Result type for type-safe error handling in TypeScript and JavaScript.

Topics

Resources

Stars

Watchers

Forks