Skip to content

Commit

Permalink
Merge pull request #58 from janglad/map-err
Browse files Browse the repository at this point in the history
mapErr()
  • Loading branch information
janglad authored Sep 22, 2024
2 parents 385844b + ad1a948 commit 1a9a394
Show file tree
Hide file tree
Showing 28 changed files with 837 additions and 1,134 deletions.
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

0 comments on commit 1a9a394

Please sign in to comment.