Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make either an array and an object #7

Merged
merged 7 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/content/contents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ course:
title: "Might Fail"
parts:
- title: "Getting Started"
slug: getting-started
filePath: /getting-started.mdx
icon: "rocket"
pages:
- title: "❌ try, catch, finally"
Expand All @@ -29,4 +31,30 @@ course:
filePath: /might-and-fail.mdx
slug: might-and-fail
type: documentation
- title: "API Reference"
slug: api-reference
filePath: /jsdocs/variables/default.mdx
icon: "file-text"
pages:
- title: "`mightFail`"
filePath: /jsdocs/functions/mightFail.mdx
slug: api-might-fail
type: documentation
- title: "`mightFailSync`"
filePath: /jsdocs/functions/mightFailSync.mdx
slug: api-might-fail-sync
type: documentation
- title: "`Either`"
filePath: /jsdocs/type-aliases/Either.mdx
slug: api-either
type: documentation
- title: "`Fail`"
filePath: /jsdocs/functions/Fail.mdx
slug: api-fail
type: documentation
- title: "`Might`"
filePath: /jsdocs/functions/Might.mdx
slug: api-might
type: documentation

---
46 changes: 46 additions & 0 deletions docs/content/getting-started.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Getting Started

* [❌ try, catch, finally](/try-catch-finally-is-bad)
* [`mightFail`](/might-fail)
* [`mightFailSync`](/might-fail-sync)
* [Static Methods](/static-methods)
* [Either Type](/either)
* [Might & Fail](/might-and-fail)

## Change the way you catch errors

That's it, that's all this library helps you do. No major re-writes for your code base, no major changes at all. Just start handling your errors in a **much** better way.

You still throw errors or let other libraries throw errors. Just stop using `try, catch, finally` and use `mightFail` or `mightFailSync` instead.

## `catch` Sucks. Guarding is Good.

Guarding allows you to handle your errors early and return from the function early, making them more readable and easier to reason about.

```ts
const [ networkError, result ] = await mightFail(fetch("/posts"));
// guard against a network error
if (networkError) {
return;
}
// guard against an error response from the server
if (!result.ok) {
return;
}
const [ convertToJSONError, posts ] = await mightFail(
result.json()
);
// guard against an error converting the response to JSON
if (convertToJSONError) {
return;
}

// success case, unnested and at the bottom of the function
posts.map((post) => console.log(post.title));
```

The success case is now the only code that is **not** nested in another block. It's also at the very bottom of the function making it easy to find.

<Important>
The sucess case is always at the bottom of the function. All of your error handling logic is next to where the error might occur.
</Important>
16 changes: 7 additions & 9 deletions docs/content/home.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ A TypeScript library for handling async and sync errors without `try` and `catch

This works for **sync** and **async** code, and you can choose the error handling style that you like.

Check out the <Link href="/motivation">motivation</Link> section for why `try,catch,finally` blocks are bad.

## Install

<SideBySide>
Expand Down Expand Up @@ -88,10 +86,10 @@ import { mightFail } from "@might/fail"


<Tabs>
<Tab name="standard">
<Tab name="tuple">
```ts
import { mightFail } from "might-fail"
const { error: networkError, result } = await mightFail(fetch("/posts"))
const [networkError, result] = await mightFail(fetch("/posts"))

if (networkError) {
// handle network error
Expand All @@ -103,7 +101,7 @@ if (!result.ok) {
return
}

const { error: convertToJSONError, result: posts } = await mightFail(
const [convertToJSONError, posts] = await mightFail(
result.json()
)

Expand All @@ -115,10 +113,10 @@ if (convertToJSONError) {
posts.map((post) => console.log(post.title))
```
</Tab>
<Tab name="tuple">
<Tab name="object">
```ts
import { mightFail } from "might-fail/tuple"
const [networkError, result] = await mightFail(fetch("/posts"))
import { mightFail } from "might-fail"
const { error: networkError, result } = await mightFail(fetch("/posts"))

if (networkError) {
// handle network error
Expand All @@ -130,7 +128,7 @@ if (!result.ok) {
return
}

const [convertToJSONError, posts] = await mightFail(
const { error: convertToJSONError, result: posts } = await mightFail(
result.json()
)

Expand Down
19 changes: 19 additions & 0 deletions docs/content/jsdocs/functions/Fail.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Function: Fail()

```ts
function Fail(error: unknown): Either<undefined>
```

A constructor function that takes an error and returns an `Either` object with undefined as the result and the error as the error.

The error will **always** be an instance of Error.

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `error` | `unknown` | |

## Returns

[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`undefined`\>
23 changes: 23 additions & 0 deletions docs/content/jsdocs/functions/Might.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Function: Might()

```ts
function Might<T>(result: NonUndefined<T>): Either<T>
```

A pure constructor function that takes a non-null value and returns an `Either` object with the value as the result and undefined as the error.

## Type Parameters

| Type Parameter |
| ------ |
| `T` |

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `result` | `NonUndefined`\<`T`\> | |

## Returns

[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\>
51 changes: 51 additions & 0 deletions docs/content/jsdocs/functions/mightFail.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Function: mightFail()

```ts
function mightFail<T>(promise: Promise<T>): Promise<Either<T>>
```

Wraps a promise in an Either to safely handle both its resolution and rejection. This function
takes a Promise of type T and returns a Promise which resolves with an object. This object
either contains a 'result' of type T if the promise resolves successfully, or an 'error' of type Error
if the promise is rejected.

## Type Parameters

| Type Parameter | Description |
| ------ | ------ |
| `T` | The type of the result value. |

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `promise` | `Promise`\<`T`\> | The promise to be wrapped in an Either. This is an asynchronous operation that should resolve with a value of type T or reject with an Error. |

## Returns

`Promise`\<[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\>\>

A Promise that resolves with an Either. This Either is a `Success<T>` with
the 'result' property set to the value resolved by the promise if successful, and 'error' as undefined.
In case of failure, it's a `Failure` with 'result' as undefined and 'error' of type Error. `error` will **always** be an instance of Error.

## Example

```ts
// Example of wrapping an async function that might fail:
async function fetchData(url: string): Promise<string> {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
}

const {error, result} = await mightFail(fetchData('https://example.com'));

if (error) {
console.error('Fetching failed:', error.message);
return;
}
console.log('Fetched data:', result);
```
21 changes: 21 additions & 0 deletions docs/content/jsdocs/functions/mightFailFunction.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Function: mightFailFunction()

```ts
function mightFailFunction<T>(promise: Promise<T>): Promise<Either<T>>
```

## Type Parameters

| Type Parameter |
| ------ |
| `T` |

## Parameters

| Parameter | Type |
| ------ | ------ |
| `promise` | `Promise`\<`T`\> |

## Returns

`Promise`\<[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\>\>
43 changes: 43 additions & 0 deletions docs/content/jsdocs/functions/mightFailSync.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Function: mightFailSync()

```ts
function mightFailSync<T>(func: () => T): Either<T>
```

Wraps a synchronous function in an Either type to safely handle exceptions. This function
executes a provided function that returns a value of type T, capturing any thrown errors.
It returns an object that either contains a 'result' of type T if the function succeeds,
or an 'error' of type Error if the function throws an error.

## Type Parameters

| Type Parameter | Description |
| ------ | ------ |
| `T` | The type of the result value.◊ |

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `func` | () => `T` | A wrapper function that is expected to invoke the throwing function. That function should return a value of type T or throw an error. |

## Returns

[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\>

An object that is either a `Success<T>` with the result property set to the value returned by `func`,
or a `Failure` with the error property set to the caught error. `Success<T>` has a 'result' of type T
and 'error' as null. `Failure` has 'result' as null and 'error' of type Error.

## Example

```ts
// Example of wrapping a synchronous function that might throw an error:
const {error, result} = mightFailSync(() => JSON.parse(""));

if (error) {
console.error('Parsing failed:', error);
return;
}
console.log('Parsed object:', result);
```
29 changes: 29 additions & 0 deletions docs/content/jsdocs/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# might-fail

## References

### makeMightFail

Re-exports makeMightFail

***

### makeMightFailSync

Re-exports makeMightFailSync

## Type Aliases

- [Either](https://mightfail.dev/type-aliases/Either.mdx)

## Variables

- [default](https://mightfail.dev/variables/default.mdx)

## Functions

- [Fail](https://mightfail.dev/functions/Fail.mdx)
- [Might](https://mightfail.dev/functions/Might.mdx)
- [mightFail](https://mightfail.dev/functions/mightFail.mdx)
- [mightFailFunction](https://mightfail.dev/functions/mightFailFunction.mdx)
- [mightFailSync](https://mightfail.dev/functions/mightFailSync.mdx)
21 changes: 21 additions & 0 deletions docs/content/jsdocs/type-aliases/Either.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Type Alias: Either\<T\>

```ts
type Either<T>: {
error: Error;
result: undefined;
} & [Error, undefined] | {
error: undefined;
result: T;
} & [undefined, T];
```

Either type represents a data structure that encapsulates a successful result or an Error.
It wraps the result of a Promise in an object, making it easier to handle errors by returning
an object that either contains a 'result' value of type T (if successful), or an 'error' of type Error.

## Type Parameters

| Type Parameter | Description |
| ------ | ------ |
| `T` | The type of the result value. |
25 changes: 25 additions & 0 deletions docs/content/jsdocs/variables/default.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Variable: default

```ts
default: {
Fail: (error: unknown) => Either<undefined>;
makeMightFail: <T>(func: T) => (...funcArgs: Parameters<T>) => Promise<Either<UnwrapPromise<ReturnType<T>>>>;
makeMightFailSync: <T>(func: T) => (...funcArgs: Parameters<T>) => Either<ReturnType<T>>;
Might: <T>(result: NonUndefined<T>) => Either<T>;
mightFail: MightFail<"standard">;
mightFailFunction: MightFailFunction<"standard">;
mightFailSync: <T>(func: () => T) => Either<T>;
};
```

## Type declaration

| Name | Type |
| ------ | ------ |
| `Fail` | (`error`: `unknown`) => [`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`undefined`\> |
| `makeMightFail` | \<`T`\>(`func`: `T`) => (...`funcArgs`: `Parameters`\<`T`\>) => `Promise`\<[`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`UnwrapPromise`\<`ReturnType`\<`T`\>\>\>\> |
| `makeMightFailSync` | \<`T`\>(`func`: `T`) => (...`funcArgs`: `Parameters`\<`T`\>) => [`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`ReturnType`\<`T`\>\> |
| `Might` | \<`T`\>(`result`: `NonUndefined`\<`T`\>) => [`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\> |
| `mightFail` | `MightFail`\<`"standard"`\> |
| `mightFailFunction` | `MightFailFunction`\<`"standard"`\> |
| `mightFailSync` | \<`T`\>(`func`: () => `T`) => [`Either`](https://mightfail.dev/type-aliases/Either.mdx)\<`T`\> |
Loading