Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ts-error-as-value

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-error-as-value - npm Package Compare versions

Comparing version 0.1.7 to 0.1.8

ttt.js

4

package.json
{
"name": "ts-error-as-value",
"version": "0.1.7",
"version": "0.1.8",
"description": "Errors as values in typescript",
"main": "lib/index.ts",
"main": "lib/index.js",
"keywords": ["result", "option", "rust", "kotlin", "errors", "errors as values", "typescript"],

@@ -7,0 +7,0 @@ "types": "lib/index.d.ts",

@@ -27,8 +27,8 @@ ### Typescript error as value

```
This will make the functions ok, err and withResult, as well as the types Ok, Err and Result globally available
This will make the functions ok, fail and withResult, as well as the types Ok, Fail and Result globally available
---
## ok and err - Basic Usage
Creating `Ok` and `Err` result objects
## ok and fail - Basic Usage
Creating `Ok` and `Fail` result objects
```ts

@@ -44,3 +44,3 @@ const { data, error } = ok("Hello");

```ts
const { data, error } = err(new Error("Error"));
const { data, error } = fail(new Error("Error"));
if (error) {

@@ -54,3 +54,3 @@ // do something with error

Wrapping the returns from functions with `err` for errors, and `ok` for non-error so that the function calling it receives a `Result` type.
Wrapping the returns from functions with `fail` for errors, and `ok` for non-error so that the function calling it receives a `Result` type.

@@ -62,3 +62,3 @@ ```ts

}
return err(new Error("Method failed"));
return fail(new Error("Method failed"));
};

@@ -82,3 +82,3 @@

}
return err(new Error("Method failed"));
return fail(new Error("Method failed"));
};

@@ -89,3 +89,3 @@

if (error) {
return err(error);
return fail(error);
}

@@ -109,3 +109,3 @@ return ok(data);

}
return err(new Error("Method failed"));
return fail(new Error("Method failed"));
};

@@ -122,3 +122,3 @@

if (error) {
return err(error);
return fail(error);
}

@@ -151,7 +151,7 @@ return ok(data);

## Error stack
One advantage of using errors as values is that we know exactly where an error was created and by whom. Taking advantage of this is still a WiP, however currently we keep track of information about all errors which we encountered in the current chain of Err results.
One advantage of using errors as values is that we know exactly where an error was created and by whom. Taking advantage of this is still a WiP, however currently we keep track of information about all errors which we encountered in the current chain of Fail results.
```ts
const fn1 = () => err(new Error("Hello"));
const fn1 = () => fail(new Error("Hello"));

@@ -177,6 +177,5 @@ const fn2 = () => fn1().mapErr(() => new Error("World"));

type Err<T, E extends Error = Error> = {
type Fail<T, E extends Error = Error> = {
data: never,
error: E,
get errorStack(): Error[],
unwrap(): void, // Returns the value, but throws an error if the result is an Error

@@ -191,3 +190,2 @@ unwrapOr<D>(defaultValue: D): D, // Returns the value or gives you a default value if it's an error

error: never,
get errorStack(): never,
unwrap(): T, // Returns the value, but throws an error if the result is an Error

@@ -200,3 +198,3 @@ unwrapOr<D>(defaultValue: D): T, // Returns the value or gives you a default value if it's an error

type Result<T, E extends Error = ErrorResult> =
| Err<T, E>
| Fail<T, E>
| Ok<T>;

@@ -207,3 +205,3 @@

```ts
function err<E extends Error>(error: E): Err<E>;
function fail<E extends Error>(error: E): Fail<E>;
function ok<T>(data: T): Ok<T>;

@@ -210,0 +208,0 @@ ```

type Ok<T> = import(".").Ok<T>;
type Err<E extends Error> = import(".").Err<E>;
type None = import(".").None;
type Fail<E extends Error> = import(".").Fail<E>;
type Result<T, E extends Error> = import(".").Result<T, E>;
declare function ok<T>(data: T): Ok<T>;
declare function err<E extends Error>(error: E): Err<E>
declare function fail<E extends Error>(error: E): Fail<E>
declare function withResult<T, E extends Error, R>(

@@ -10,0 +9,0 @@ fn: (...args: T[]) => R

@@ -1,2 +0,2 @@

import { ok, err } from ".";
import { ok, fail } from ".";
import { withResult } from "./with-result";

@@ -6,8 +6,8 @@

(window as any).ok = ok;
(window as any).err = err;
(window as any).fail = fail;
(window as any).withResult = withResult;
} else {
(globalThis as any).ok = ok;
(globalThis as any).err = err;
(globalThis as any).fail = fail;
(globalThis as any).withResult = withResult;
}

@@ -1,13 +0,10 @@

import { ErrorResult, isErrorResult } from "./error-result";
export type None = null;
export type Err<T, E extends Error = Error> = {
data: never,
export type Fail<E extends Error = Error> = {
data: null,
error: E,
get errorStack(): Error[],
unwrap(): void, // Returns the value, but throws an error if the result is an Error
unwrapOr<D>(defaultValue: D): D, // Returns the value or gives you a default value if it's an error
mapErr<E2 extends Error>(fn: (err: E) => E2): Err<T, E2>, // If the result is an error, map the error to another error
andThen<N>(fn: (data: never) => N): Err<T, E> // If the result is not an error, map the data in it
mapFail<E2 extends Error>(fn: (fail: E) => E2): Fail<E2>, // If the result is an error, map the error to another error
andThen<N>(fn: (data: never) => N): Fail<E> // If the result is not an error, map the data in it
};

@@ -17,7 +14,6 @@

data: T,
error: never,
get errorStack(): never,
error: null,
unwrap(): T, // Returns the value, but throws an error if the result is an Error
unwrapOr<D>(defaultValue: D): T, // Returns the value or gives you a default value if it's an error
mapErr<E2 extends Error>(fn: (err: never) => E2): Ok<T>, // If the result is an error, map the error to another error
mapFail<E2 extends Error>(fn: (fail: never) => E2): Ok<T>, // If the result is an error, map the error to another error
andThen<N>(fn: (data: T) => N): Ok<N> // If the result is not an error, map the data in it

@@ -27,44 +23,16 @@ };

export type Result<
T, E extends Error = ErrorResult
> = Err<T, E> | Ok<T>;
T, E extends Error = Error
> = Fail<E> | Ok<T>;
export const err = <E extends Error>(
export const fail = <E extends Error>(
error: E
): Err<None, E> => {
if (isErrorResult(error)) {
return {
data: null as never,
error: ErrorResult.fromExistingResult(error),
get errorStack() {
return error._errorStack;
},
unwrap(): void {
throw error;
},
mapErr<E2 extends Error>(fn: (err: E) => E2): Err<None, E2> {
return removeLastErrorStackItem(err<E2>(ErrorResult.new(error, fn(error))));
},
unwrapOr<D>(defaultValue: D): D {
return defaultValue;
},
andThen(): Err<None, E> {
return this;
}
};
}
const errorResult = ErrorResult.fromError(error);
): Fail<E> => {
return {
data: null as never,
error: errorResult,
get errorStack() {
if (!isErrorResult(errorResult)) {
return [];
}
return errorResult._errorStack;
},
data: null,
error: error,
unwrap() {
throw error;
},
mapErr<E2 extends Error>(fn: (err: E) => E2): Err<None, E2> {
return removeLastErrorStackItem(err<E2>(ErrorResult.new(error, fn(error))));
mapFail<E2 extends Error>(fn: (err: E) => E2): Fail<E2> {
return fail<E2>(fn(error));
},

@@ -74,3 +42,3 @@ unwrapOr<D>(defaultValue: D): D {

},
andThen(): Err<None, E> {
andThen(): Fail<E> {
return this;

@@ -85,10 +53,7 @@ }

data,
error: null as never,
get errorStack() {
return [] as never;
},
error: null,
unwrap(): T {
return data;
},
mapErr(): Ok<T> {
mapFail(): Ok<T> {
return this;

@@ -104,9 +69,1 @@ },

const removeLastErrorStackItem = <T, E extends Error>(result: Err<T, E>): Err<T, E> => {
if (result.error) {
const newErrorResult: any = { ...result.error };
newErrorResult._errorStack = newErrorResult._errorStack.slice(0, -1);
return { ...result, error: newErrorResult };
}
return result;
};

@@ -1,3 +0,2 @@

import { err, Err, Ok, ok } from "../src";
import { isErrorResult } from "./error-result";
import { fail, Fail, Result, Ok, ok } from "../src";

@@ -7,18 +6,10 @@

describe("Err type", () => {
let errorInstance: Err<null>;
describe("Fail type", () => {
let errorInstance: Result<string, Error>;
const testError = new Error("Test error");
beforeEach(() => {
errorInstance = err(testError);
errorInstance = fail(testError);
});
it("should return error for Err type", () => {
expect(isErrorResult(errorInstance.error)).toBeTruthy();
});
it("should return error stack for Err type", () => {
expect(errorInstance.errorStack).toEqual(expect.arrayContaining([ testError ]));
});
it("should throw error on unwrap for Err type", () => {

@@ -34,6 +25,5 @@ expect(() => errorInstance.unwrap()).toThrow(testError);

const newError = new Error("New error");
const { error } = errorInstance.mapErr(() => newError);
expect(isErrorResult(error)).toBeTruthy();
if (isErrorResult(error)) {
expect(error._errorStack[error._errorStack.length - 1].message).toBe(newError.message);
const { error } = errorInstance.mapFail(() => newError);
if (error) {
expect(error.message).toBe(newError.message);
}

@@ -73,3 +63,3 @@ });

it("should return itself on mapErr for Ok type", () => {
const result = okInstance.mapErr(() => new Error("New error"));
const result = okInstance.mapFail(() => new Error("New error"));
expect(JSON.stringify(result)).toEqual(JSON.stringify(okInstance));

@@ -76,0 +66,0 @@ });

@@ -1,2 +0,2 @@

import { err, ok, Result, Ok, Err } from "./index";
import { fail, ok, Result, Ok, Fail } from "./index";

@@ -6,3 +6,3 @@ export const isPromise = <T>(value: T | Promise<T>): value is Promise<T> =>

/** Function which wraps another function and returns an Err result if the wrapped function throws an error,
/** Function which wraps another function and returns a Fail result if the wrapped function throws an error,
* and returns an Ok result if the wrapped function does not. */

@@ -19,3 +19,3 @@ export const withResult = <T, E extends Error, R>(

.then(value => ok(value) as Ok<typeof value>)
.catch(e => err(e) as Err<E>) as (R extends Promise<infer u> ? Promise<Result<u, E>> : Result<R, E>);
.catch(e => fail(e) as Fail<E>) as (R extends Promise<infer u> ? Promise<Result<u, E>> : Result<R, E>);
}

@@ -25,3 +25,3 @@ return ok(data) as any;

const e = error instanceof Error ? error : new Error("Unknown error");
return err(e) as any;
return fail(e) as any;
}

@@ -28,0 +28,0 @@ };

@@ -26,3 +26,3 @@ // Assuming a jest-like syntax for demonstration purposes.

it("should return Err for errors", () => {
it("should return Fail for errors", () => {
const errorFunc = (): Result<null, Error> => {

@@ -45,3 +45,3 @@ throw new Error("Oops!");

it("should return Err for rejected promises", async () => {
it("should return Fail for rejected promises", async () => {
const errorAsyncFunc = async () => {

@@ -48,0 +48,0 @@ throw new Error("Oops async!");

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc