npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

base-ts-result

v3.1.1

Published

Better error handling stolen from rust

Downloads

15

Readme

Base Ts Result

Better error handling stolen from rust. Return result values instead of throwing exceptions. Handle every error result with minimum nesting.

npm npm NPM

Install

npm i base-ts-result
yarn add base-ts-result
pnpm add base-ts-result

Example

import { Ok, Err, type Result } from 'base-ts-result';

const gonnaThrow = () => {
    throw new Error("you have to catch me or i'll crash the app");
};

const res = toResult(gonnaThrow);
res.isErr() // true

/**
 * @description returns random value, returns error if the value <= 0.5
 */
const getRes = (): Result<number, string> => {
    const val = Math.random();

    if (val > 0.5) {
        return Ok(val);
    }

    return Err('number is too low');
};

/**
 * @description returns random value or zero if random value <= 0.5
 */
const handleRes = () => {
    return getRes()
        .inspect(v => console.log(`Got ok value ${v}`))
        .inspectErr(e => console.error(e))
        .unwrapOr(0);
};

const val = handleRes();
console.log(val);

Docs

Constructors

Handy functions to create Result objects

import { Ok, Err } from 'base-ts-result';

// create success Result
const okRes = Ok('success');

// create error Result
const errRes = Err('failure');

Result

Interface that contains operation result and interaction methods

Result.unwrap()

Unwraps result value or throws an error if the result is Err.

import { Ok, Err } from 'base-ts-result';

let res = Ok('great success');
console.log(res.unwrap());

res = Err('fatal error');
res.unwrap(); // throws an error

Result.unwrapErr()

Unwraps result error or throws an error if the result is Ok.

import { Ok, Err } from 'base-ts-result';

let res = Ok('great success');
res.unwrapErr(); // throws an error

res = Err('fatal error');
res.unwrapErr(); // return the error

Result.unwrapOr(altValue)

Unwraps original value or replaces it with provided alternative if the result is Err.

import { Ok, Err } from 'base-ts-result';

let res = Ok('great success');
console.log(res.unwrapOr('not that great')); // prints great success

res = Err('fatal error');
console.log(res.unwrapOr('not that great')); // prints not that great

Result.unwrapOrElse(factory: (err: Err))

Unwraps original value if the result is Ok, otherwise returns value from factory function.

let res = Ok(5);
console.log(res.unwrapOrElse(() => 0)); // prints 5

res = Err('error msg');
console.log(res.unwrapOrElse(() => "not a number")); // prints not a number

Result.expect(message)

Unwraps result or throws new Error with provided message.

let res = Ok(5);
console.log(res.expect('provided message')); // 5

res = Err('error msg');
console.log(res.expect('provided message')); // throws an error: 'provided message'

Result.expectError(message)

Unwraps error from result or throws new Error with provided message.

let res = Ok(5);
console.log(res.expectErr('provided message')); // Exception: provided message

res = Err('error msg');
console.log(res.expectErr('provided message')); // 'error msg'

Result.isOk()

Returns true if result is Ok, otherwise returns false.

let res = Ok(5);
console.log(res.isOk()); // true

res = Err('error msg');
console.log(res.isOk()); // false

Result.isErr()

Returns true if result is Err, otherwise returns false.

let res = Ok(5);
console.log(res.isErr()); // false

res = Err('error msg');
console.log(res.isOk()); // true

Result.ok()

Returns value if result is Ok, or undefined if it's Err.

let res = Ok(5);
console.log(res.ok()); // 5

res = Err('error msg');
console.log(res.ok()); // undefined

Result.err()

Returns error value if result is Err, or undefined if it's Ok.

let res = Ok(5);
console.log(res.err()); // undefined

res = Err('error msg');
console.log(res.err()); // error msg

Result.map(mapper)

Returns new result with mapped value.

const res = Ok(5);
const mappedRes = res.map((val) => val + 1);

console.log(mappedRes.unwrap()); // 6

Result.mapErr(mapper)

Returns new result with mapped error value.

const res = Err('error msg');
const mappedRes = res.mapErr(err => err + ' suffix');
console.log(mappedRes.unwrapErr()); // error msg suffix

Result.mapOrElse(mapper, fallback)

Returns new result with mapped ok value & mapped error value.

const mapOk = (val => val + 1);
const mapErr = (err => err + ' suffix');

console.log(Ok(5).unwrap()) // 6
console.log(Err('error msg').unwrapErr()) // error message suffix

Result.inspect()

Will run provided inspector if result is Ok.

let res = Ok(5);
res.inspect((val) => console.log(val)); // prints 5

res = Err('error msg');
res.inspect((val) => console.log(val)); // prints nothing

Result.inspectErr()

Will run provided inspector if result is Err.

let res = Ok(5);
res.inspect((val) => console.log(val)); // prints noting

res = Err('error msg');
res.inspect((val) => console.log(val)); // prints error msg

Result.toAsync()

Returns new async result constructed from current result.

const res = Ok(5);
const asyncRes = res.toAsync();

Result interface

interface Result<Val, Err> {
    // Contained Promise
    value: Val | Err;

    // Queries
    unwrap(): Val;
    unwrapErr(): Err;
    unwrapOr(altVal: Val): Val;
    unwrapOrElse(altValFactory: (err: Err) => Val): Val;
    expect(msg: string): Val;
    expectErr(msg: string): Err;
    isOk(): this is OK<Val>;
    isErr(): this is ERR<Err>;
    ok(): Val|undefined,
    err(): Err|undefined,

    // Mappers
    map<MappedVal>(mapper: (val: Val) => MappedVal): Result<MappedVal, Err>;
    mapOrElse<MappedVal>(mapper: (val: Val) => MappedVal, fallback: (err: Err) => MappedVal): Result<MappedVal, Err>;
    mapErr<MappedErr>(mapper: (err: Err) => MappedErr): Result<Val, MappedErr>;

    // Utilities
    inspect(inspector: (val: Val) => any): Result<Val, Err>;
    inspectErr(inspector: (err: Err) => any): Result<Val, Err>;
    toAsync(): AsyncResult<Val, Err>;
}

AsyncResult

Class that contains operation result and interaction methods for async code

Static AsyncResult.fromPromise(promise)

Creates async result from promise.

import { AsyncResult } from 'base-ts-result';

const resPromise = AsyncResult.fromPromise(Promise.resolve(1));

Static AsyncResult.fromResult(result)

Creates async result from synchronous result.

import { AsyncResult } from 'base-ts-result';

const resPromise = AsyncResult.fromResult(Ok(5));

Static AsyncResult.fromResultPromise(resultPromise)

Creates async result from result promise.

import { AsyncResult } from 'base-ts-result';

const resPromise = AsyncResult.fromResult(Promise.resolve(Ok(5)));

AsyncResult interface

// Async result implementation for more ergonomic usage of Results with async code
class AsyncResult<Val, Err> {
    // Contained promise
    promise: ResultPromise<Val, Err>; 

    // Creators
    static fromPromise<Val>(promise: Promise<Val>): AsyncResult<Val, unknown>;
    static fromResult<Val, Err>(result: Result<Val, Err>): AsyncResult<Val, Err>;
    static fromResultPromise<Val, Err>(result: ResultPromise<Val, Err>): AsyncResult<Val, Err>;

    // Queries
    async unwrap(): Promise<Val>;
    async unwrapErr(): Promise<Err>;
    async unwrapOr(altVal: Val): Promise<Val>;
    async unwrapOrElse(altValFactory: (err: Err) => AsyncMapped<Val>): Promise<Val>;
    async expect(msg: string): Promise<Val>;
    async expectErr(msg: string): Promise<Err>;
    async isOk(): Promise<boolean>;
    async isErr(): Promise<boolean>;
    async ok(): Promise<Val|undefined>;
    async err(): Promise<Err|undefined>;

    // Mappers
    map<NewVal>(mapper: (val: Val) => AsyncMapped<NewVal>): AsyncResult<NewVal, Err>;

    mapOrElse<NewVal>(
        mapper: (val: Val) => AsyncMapped<NewVal>,
        fallback: (err: Err) => AsyncMapped<NewVal>
    ): AsyncResult<NewVal, Err>;

    mapErr<NewErr>(mapper: (err: Err) => AsyncMapped<NewErr>): AsyncResult<Val, NewErr>;

    // Utilities
    inspect(inspector: (val: Val) => any): AsyncResult<Val, Err>;
    inspectErr(inspector: (err: Err) => any): AsyncResult<Val, Err>;
}

Helpers

toResult(fn)

Converts function return value to result.

import { toResult } from 'base-ts-result';

let res = toResult(() => 2);
console.log(res.unwrap()); // prints 2

res = toResult(() => throw new Err());
console.log(res.unwrapErr()); // prints error

resultify(fn, mapErr)

Wraps the original function with resultifier.

const rawFn = (a: number) => {
    if (a < 0) {
        throw new Error('not today')
    }

    return a;
};

const fn = resultify(
    rawFn,
    err => err.message
);

const res = fn(-2); // Result<number, string>
res.err() // 'not today'

asyncResultify(fn, mapErr)

Converts plain async function to function that return async result.

const rawFn = async (a: number) => {
    if (a < 0) {
        throw new Error('not today')
    }

    return a;
};

const fn = asyncResultify(
    rawFn,
    async err => err.message
); // (a: number) => AsyncResult<number, string>

const res = fn(-2); // AsyncResult<number, string>
await res.err() // 'not today'

createAsyncResult(fn: () => Promise)

Converts function that returns a promise with sync result into function that returns async result.

const resultPromiseFn = async (a: number): ResultPromise<number, string> => {
    await new Promise(() => {
        setTimeOut(() => Promise.resolve(), 100)
    });

    if (a < 0) {
        return Err('err');
    }

    return Ok(a);;
};

// Manual, not convenient way
const valueOne = (await resultPromiseFn(2)).unwrap();

// Using helper
const fn = createAsyncResultFn(resultPromiseFn); // (a: number) => AsyncResult<number, string>
const valueTwo = await fn(2).unwrap(); // Same result, with more convenient async handling

toAsyncResult(promise)

Creates result from a promise.

const promise = Promise.reject();
const result = toAsyncResult(promise);

Sources