2.1.0 • Published 1 year ago

okerr v2.1.0

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

A practical Result type inspired by Rust Result.

Build & tests npm bundle size

Why

Errors are normal in an applications lifecycle, they should be regular values and we should be able to know them by looking at function type signatures.

try/catch should be reserved to unexpected events recovery.

Goals

  • integrate nicely with typescript/javascript
  • small api surface
  • practical over academical

install

npm i okerr

usage

import { Ok, Err } from "okerr";

or

import "okerr/globals";

will import the Ok and Err global functions, Result type and add the toResult method to Promises.

API

Ok/Err

import { Ok, Err } from "okerr";
// import 'okerr/globals';

enum ValidationErrors {
  NameEmpty = "NameEmpty",
  EmailEmpty = "EmailEmpty",
}

interface Input {
  name: string;
  email: string;
}

// function validate(input: Input): Err<ValidationErrors> | Ok<Input>
function validate(input: Input) {
  if (!input.name) {
    return Err(ValidationErrors.NameEmpty);
  }
  if (!input.email) {
    return Err(ValidationErrors.EmailEmpty);
  }
  return Ok(input);
}

toResult

catch exceptions from a Promise into a Promise<Ok | Err>

  import { toResult } from 'okerr';
  // or
  import 'okerr/globals';

  async function someAsyncFunction(value: string): string {
    ...
  }

  const result = await toResult<ApiErrors>(someAsyncFunction(value));
  // or
   const result = await toResult(someAsyncFunction(value), e => e as ApiErrors);
  // or if import 'okerr/globals'
  const result = await someAsyncFunction(value).toResult<ApiErrors>();
  // result: Ok<string> | Err<ApiErrors>

mapOk

naturally bubble errors up the callstack until you want to deal with them.

notice how the following function do not throw and instead describe precisely all errors it might return without any visible error handling.

// function getItemsFromApi(input: Input): Promise<Err<ValidationErrors> | Ok<string> | Err<ApiErrors>>
async function getItemsFromApi(input: Input) {
  const validateResult = validate(input);
  // validateResult: Err<ValidationErrors> | Ok<Input>

  const apiCallResult = await validateResult.mapOk(async (value) => {
    return await someAsyncFunction(value).toResult<ApiErrors>();
  });
  // apiCallResult: Err<ValidationErrors> | Ok<string> | Err<ApiErrors>

  return apiCallResult;
}

isErr

const result = validate({ name: "John", email: "john@email.com" });
// result: Err<ValidationErrors> | Ok<Input>
if (result.isErr()) {
  // result.error: ValidationErrors
  toast(translate(result.error));
  return;
}

// result.data: Input
console.log(result.data);

unwrap

const { error, data } = validate({ name: "John", email: "john@email.com" });
// error: ValidationErrors | undefined
// data: Input | undefined

if (error) {
  // error: ValidationErrors
  toast(translate(error));
  return;
}
// data: Input
console.log(data);

resultify

transform a function returning Promise into a function returning Promise<Ok | Err>

import { resultify } from "okerr";

const someAsyncResultFunction = resultify(someAsyncFunction);
// someAsyncResultFunction: <E = unknown>(value: string) => Promise<Ok<string> | Err<E>>

const result = await someAsyncResultFunction<ApiErrors>(value);
// result: Ok<string> | Err<ApiErrors>

// or
const someAsyncResultFunction = resultify(someAsyncFunction)<ApiErrors>;
// someAsyncResultFunction: (value: string) => Promise<Ok<string> | Err<ApiErrors>>

const result = await someAsyncResultFunction(value);
// result: Ok<string> | Err<ApiErrors>

Result

keep return types readable by merging Ok and Err types

import { Result } from "okerr";
// import 'okerr/globals';

// function getItemsFromApi(input: Input): Promise<Result<string, ValidationErrors | ApiErrors>>
async function getItemsFromApi(
  input: Input
): Result<string, ValidationErrors | ApiErrors> {
  const validateResult = validate(input);
  // validateResult: Err<ValidationErrors> | Ok<Input>

  const apiCallResult = await validateResult.mapOk(async (value) => {
    return await someAsyncFunction(value).toResult<ApiErrors>();
  });
  // apiCallResult: Err<ValidationErrors> | Ok<string> | Err<ApiErrors>

  return apiCallResult;
}
2.1.0

1 year ago

2.0.0

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.0

1 year ago