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

Map err #58

Merged
merged 29 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
520788f
set up type params
janglad Sep 21, 2024
bbe432a
add temp inferance types, fix default err
janglad Sep 21, 2024
c347c7c
Start implementing (parent only returning err no longer possible)
janglad Sep 21, 2024
e37ed0b
set error type for catch
janglad Sep 21, 2024
9d774af
implement (with regression in error types)
janglad Sep 21, 2024
ed609b6
allow override if default error handler is used, add tests
janglad Sep 21, 2024
5e691c4
add changeset about change error handler behavior in chaining
janglad Sep 21, 2024
75e06de
fix typings for err
janglad Sep 21, 2024
ff307a8
add type test indicating chaining is not possible when parent returns…
janglad Sep 21, 2024
28efe34
Merge input/output errors again
janglad Sep 21, 2024
dd2b5d5
clean up unused types/exports a bit
janglad Sep 21, 2024
48de5df
remove parent merged errors
janglad Sep 21, 2024
d6ee507
Remove unused types
janglad Sep 21, 2024
d298409
remove THandlerRes
janglad Sep 22, 2024
27569b1
remove TCatchHandlerRes
janglad Sep 22, 2024
dcc9fa2
clean up types, fix output infer on action, add test case
janglad Sep 22, 2024
adca187
remove TActionArrgs
janglad Sep 22, 2024
8c50a2d
get rid of asAction
janglad Sep 22, 2024
c86e7ff
add changeset
janglad Sep 22, 2024
7751841
update docs to reflect changes to error return
janglad Sep 22, 2024
f1571f0
Rename infer types
janglad Sep 22, 2024
50075df
Further rename types, update docs
janglad Sep 22, 2024
b78293b
add changeset
janglad Sep 22, 2024
668aca0
Merge pull request #59 from janglad/remove-action-err
janglad Sep 22, 2024
543dafe
implement map err at type level, at type test
janglad Sep 22, 2024
ecb12c7
implement err map, add simple tes
janglad Sep 22, 2024
11f5e76
add few more map tests
janglad Sep 22, 2024
3bfac9b
add mapErr doc
janglad Sep 22, 2024
ad1a948
add changeset
janglad Sep 22, 2024
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
5 changes: 5 additions & 0 deletions .changeset/blue-kids-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"safe-fn": patch
---

- add `mapErr()` function
5 changes: 5 additions & 0 deletions .changeset/dirty-chicken-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"safe-fn": patch
---

- removes asAction, all errors are now stripped by default
5 changes: 5 additions & 0 deletions .changeset/honest-buses-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"safe-fn": patch
---

- Use child `.catch()` handler if parent didn't define one
6 changes: 6 additions & 0 deletions .changeset/short-foxes-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"safe-fn-react": patch
"safe-fn": patch
---

- Rename some Infer types, see docs.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,16 @@ type res = ResultAsync<
| { code: "NOT_AUTHORIZED" }
| {
code: "INPUT_PARSING";
cause: z.ZodError<{ title: string; description: string }>;
cause: {
formattedError: z.ZodFormattedError<{
title: string;
description: string;
}>;
flattenedError: z.ZodFlattenedError<{
title: string;
description: string;
}>;
};
}
>;
```
Expand Down
4 changes: 0 additions & 4 deletions apps/docs/content/docs/create/callbacks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ Starts execution after output parsing has completed if you defined a schema, oth
.onError(async (args) => {
/*
(parameter) args: {
asAction: boolean
input: {
firstName: string;
lastName: string;
Expand All @@ -114,7 +113,6 @@ Starts execution after output parsing has completed if you defined a schema, oth

Starts execution after the first encountered `Err` return while executing your SafeFn. Takes in the following parameters:

- `asAction`: wether the safe-fn was run as an action (`createAction()()`) or not (`run()`). This can be helpful the narrow down the type of `error`.
- `unsafeRawInput`: the raw input passed when running your SafeFn. Keep in mind this can contain additional properties when using one SafeFn as the parent of another!
- `input`: the results of parsing `unsafeRawInput` through your input schema if you defined one and parsing was successful, otherwise `undefined`.
- `ctx`: the `Ok` value of your parent safe-fn if you defined one and execution was successful, otherwise undefined
Expand All @@ -128,7 +126,6 @@ Starts execution after the first encountered `Err` return while executing your S
.onComplete(async (args) => {
/*
(parameter) args: {
asAction: boolean
input: {
firstName: string;
lastName: string;
Expand All @@ -149,7 +146,6 @@ Starts execution after the first encountered `Err` return while executing your S

Starts execution after either `onSuccess()` or `onError()` is **called** (not finished). Takes in the following parameters:

- `asAction`: wether the safe-fn was run as an action (`createAction()()`) or not (`run()`). This can be helpful the narrow down the type of `error`.
- `unsafeRawInput`: the raw input passed when running your SafeFn. Keep in mind this can contain additional properties when using one SafeFn as the parent of another!
- `input`: the results of parsing `unsafeRawInput` through your input schema if you defined one and parsing was successful, otherwise `undefined`.
- `ctx`: the `Ok` value of your parent safe-fn if you defined one and execution was successful, otherwise undefined
Expand Down
43 changes: 12 additions & 31 deletions apps/docs/content/docs/create/input-output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,6 @@ const mySafeFunction = SafeFn.new()

When parsing is not successful, your handler function is not called and the error is returned. As such, the following types are added to the return type of the function:

- when using `run()`

```ts
ResultAsync<{
never,
{
code: "INPUT_PARSING";
cause: z.ZodError<{
firstName: string;
lastName: string;
}>;
}
}>;
```

- when using `createAction()()` (full errors are stripped here as classes can not be sent via a Server Action and stack traces should not be shipped to the client)

```ts
ActionResult<
never,
Expand All @@ -62,6 +45,12 @@ ActionResult<
>;
```

<Callout type="info">
The full Zod error is not returned as SafeFn is meant to be used at the edge
of your application, stack traces should not be sent to the client and it's
not possible to serialize an instance of `Error`s.
</Callout>

<Callout type="info">
When using a [parent](/docs/create/chaining), the schema of the Zod error is
merged with the possible input parsing errors from all parent SafeFns. This is
Expand Down Expand Up @@ -134,20 +123,6 @@ const mySafeFunction = SafeFn.new()

When output parsing is not successful, an `Err` is returned. The following types are added to the return type:

- when using `run()`

```ts
ResultAsync<{
never,
{
code: "OUTPUT_PARSING";
cause: z.ZodError<{ fullName: string }>;
};
}>;
```

- when using `createAction()()` (full errors are stripped here as classes can not be sent via a Server Action and stack traces should not be shipped to the client)

```ts
ActionResult<
never,
Expand All @@ -161,6 +136,12 @@ ActionResult<
>;
```

<Callout type="info">
The full Zod error is not returned as SafeFn is meant to be used at the edge
of your application, stack traces should not be sent to the client and it's
not possible to serialize an instance of `Error`s.
</Callout>

<Callout type="info">
When using a [parent](/docs/create/chaining), the schema of the Zod error is
merged with the possible output parsing errors from all parent SafeFns. This
Expand Down
3 changes: 2 additions & 1 deletion apps/docs/content/docs/create/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"input-output",
"handler",
"uncaught-errors",
"callbacks"
"callbacks",
"modifying-result"
],
"defaultOpen": true
}
47 changes: 47 additions & 0 deletions apps/docs/content/docs/create/modifying-result.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Modifying result type
---

Often times you want to filter out some specific errors from the client. Typically you'll handle this by calling NeverThrow's own `mapErr()` on your returned/yielded results, however sometimes it can be handy to do this globally for your SafeFn.
You can modify the error type of the SafeFn by using `.mapErr()`. This is a function that takes in an argument of the original error type (see ), and returns a value that will set the new error type.

As an example:

```ts
// Fake function declaration
declare const generateText: (
prompt: string,
) => ResultAsync<string, { code: "NO_CREDITS_REMAINING" }>;

const generateTodo = createSafeFn()
.input(z.object({ prompt: z.string() }))
.safeHandler(async function* (args) {
const todo = yield* generateText(
`Make todo based on ${args.input.prompt}`,
).safeUnwrap();
return ok(todo);
})
.mapErr((e) => {
if (e.code === "NO_CREDITS_REMAINING") {
// Don't let em know funds are running low lmao
return {
code: "UNKNOWN_ERROR",
} as const;
}
return e;
});
```

The possible `Error` type when running this function will be

```ts
type Res =
| {
code: "UNKNOWN_ERROR";
}
| {
code: "INPUT_PARSING";
cause: ...;
}
| { code: "UNCAUGHT_ERROR"; cause: ... };
```
11 changes: 10 additions & 1 deletion apps/docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,16 @@ type res = ResultAsync<
| { code: "NOT_AUTHORIZED" }
| {
code: "INPUT_PARSING";
cause: z.ZodError<{ title: string; description: string }>;
cause: {
formattedError: z.ZodFormattedError<{
title: string;
description: string;
}>;
flattenedError: z.typeToFlattenedError<{
title: string;
description: string;
}>;
};
}
>;
```
Expand Down
63 changes: 1 addition & 62 deletions apps/docs/content/docs/run/return-type.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ A union that can contain the following errors:

### Input parsing

When using `.run()`

```ts
type E = {
code: "INPUT_PARSING";
cause: z.ZodError<T>;
};
```

when using `.createAction()` full errors are stripped as classes can not be sent via a Server Action and stack traces should not be shipped to the client

```ts
type E = {
code: "INPUT_PARSING";
Expand Down Expand Up @@ -92,17 +81,6 @@ type E = {

### Output parsing

When using `.run()`

```ts
type E = {
code: "OUTPUT_PARSING";
cause: z.ZodError<T>;
};
```

when using `.createAction()` full errors are stripped as classes can not be sent via a Server Action and stack traces should not be shipped to the client

```ts
type E = {
code: "OUTPUT_PARSING";
Expand Down Expand Up @@ -175,46 +153,7 @@ const child = createSafeFn()
});
```

The return type of `child.run()` will be:

```ts
type Res = ResultAsync<
{
childOut: string;
},
// Merged error from parent and child
| {
code: "INPUT_PARSING";
cause: z.ZodError<{
parentIn: string;
childIn: string;
}>;
}
// Yielded error in parent
| {
code: "TOO_LOW!";
}
// Parent did not specify a catch handler, so default is used
| {
code: "UNCAUGHT_ERROR";
cause: "An uncaught error occurred. You can implement a custom error handler by using `catch()`";
}
// Specified in child catch handler
| {
code: "Woops!";
}
// Output parsing error
| {
code: "OUTPUT_PARSING";
cause: z.ZodError<{
parentOut: string;
childOut: string;
}>;
}
>;
```

The result of calling `child.createAction()` through the `useServerAction()` hook will be:
The return type of `child.run()` or calling `child.createAction()` through the `useServerAction()` hook will be:

```ts
type Res = ResultAsync<
Expand Down
Loading
Loading