Skip to content

Commit 1a9a394

Browse files
authored
Merge pull request #58 from janglad/map-err
mapErr()
2 parents 385844b + ad1a948 commit 1a9a394

28 files changed

+837
-1134
lines changed

.changeset/blue-kids-study.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"safe-fn": patch
3+
---
4+
5+
- add `mapErr()` function

.changeset/dirty-chicken-whisper.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"safe-fn": patch
3+
---
4+
5+
- removes asAction, all errors are now stripped by default

.changeset/honest-buses-add.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"safe-fn": patch
3+
---
4+
5+
- Use child `.catch()` handler if parent didn't define one

.changeset/short-foxes-care.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"safe-fn-react": patch
3+
"safe-fn": patch
4+
---
5+
6+
- Rename some Infer types, see docs.

README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,16 @@ type res = ResultAsync<
8888
| { code: "NOT_AUTHORIZED" }
8989
| {
9090
code: "INPUT_PARSING";
91-
cause: z.ZodError<{ title: string; description: string }>;
91+
cause: {
92+
formattedError: z.ZodFormattedError<{
93+
title: string;
94+
description: string;
95+
}>;
96+
flattenedError: z.ZodFlattenedError<{
97+
title: string;
98+
description: string;
99+
}>;
100+
};
92101
}
93102
>;
94103
```

apps/docs/content/docs/create/callbacks.mdx

-4
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ Starts execution after output parsing has completed if you defined a schema, oth
9393
.onError(async (args) => {
9494
/*
9595
(parameter) args: {
96-
asAction: boolean
9796
input: {
9897
firstName: string;
9998
lastName: string;
@@ -114,7 +113,6 @@ Starts execution after output parsing has completed if you defined a schema, oth
114113

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

117-
- `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`.
118116
- `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!
119117
- `input`: the results of parsing `unsafeRawInput` through your input schema if you defined one and parsing was successful, otherwise `undefined`.
120118
- `ctx`: the `Ok` value of your parent safe-fn if you defined one and execution was successful, otherwise undefined
@@ -128,7 +126,6 @@ Starts execution after the first encountered `Err` return while executing your S
128126
.onComplete(async (args) => {
129127
/*
130128
(parameter) args: {
131-
asAction: boolean
132129
input: {
133130
firstName: string;
134131
lastName: string;
@@ -149,7 +146,6 @@ Starts execution after the first encountered `Err` return while executing your S
149146

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

152-
- `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`.
153149
- `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!
154150
- `input`: the results of parsing `unsafeRawInput` through your input schema if you defined one and parsing was successful, otherwise `undefined`.
155151
- `ctx`: the `Ok` value of your parent safe-fn if you defined one and execution was successful, otherwise undefined

apps/docs/content/docs/create/input-output.mdx

+12-31
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,6 @@ const mySafeFunction = SafeFn.new()
2323

2424
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:
2525

26-
- when using `run()`
27-
28-
```ts
29-
ResultAsync<{
30-
never,
31-
{
32-
code: "INPUT_PARSING";
33-
cause: z.ZodError<{
34-
firstName: string;
35-
lastName: string;
36-
}>;
37-
}
38-
}>;
39-
```
40-
41-
- 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)
42-
4326
```ts
4427
ActionResult<
4528
never,
@@ -62,6 +45,12 @@ ActionResult<
6245
>;
6346
```
6447

48+
<Callout type="info">
49+
The full Zod error is not returned as SafeFn is meant to be used at the edge
50+
of your application, stack traces should not be sent to the client and it's
51+
not possible to serialize an instance of `Error`s.
52+
</Callout>
53+
6554
<Callout type="info">
6655
When using a [parent](/docs/create/chaining), the schema of the Zod error is
6756
merged with the possible input parsing errors from all parent SafeFns. This is
@@ -134,20 +123,6 @@ const mySafeFunction = SafeFn.new()
134123

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

137-
- when using `run()`
138-
139-
```ts
140-
ResultAsync<{
141-
never,
142-
{
143-
code: "OUTPUT_PARSING";
144-
cause: z.ZodError<{ fullName: string }>;
145-
};
146-
}>;
147-
```
148-
149-
- 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)
150-
151126
```ts
152127
ActionResult<
153128
never,
@@ -161,6 +136,12 @@ ActionResult<
161136
>;
162137
```
163138

139+
<Callout type="info">
140+
The full Zod error is not returned as SafeFn is meant to be used at the edge
141+
of your application, stack traces should not be sent to the client and it's
142+
not possible to serialize an instance of `Error`s.
143+
</Callout>
144+
164145
<Callout type="info">
165146
When using a [parent](/docs/create/chaining), the schema of the Zod error is
166147
merged with the possible output parsing errors from all parent SafeFns. This

apps/docs/content/docs/create/meta.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"input-output",
77
"handler",
88
"uncaught-errors",
9-
"callbacks"
9+
"callbacks",
10+
"modifying-result"
1011
],
1112
"defaultOpen": true
1213
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: Modifying result type
3+
---
4+
5+
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.
6+
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.
7+
8+
As an example:
9+
10+
```ts
11+
// Fake function declaration
12+
declare const generateText: (
13+
prompt: string,
14+
) => ResultAsync<string, { code: "NO_CREDITS_REMAINING" }>;
15+
16+
const generateTodo = createSafeFn()
17+
.input(z.object({ prompt: z.string() }))
18+
.safeHandler(async function* (args) {
19+
const todo = yield* generateText(
20+
`Make todo based on ${args.input.prompt}`,
21+
).safeUnwrap();
22+
return ok(todo);
23+
})
24+
.mapErr((e) => {
25+
if (e.code === "NO_CREDITS_REMAINING") {
26+
// Don't let em know funds are running low lmao
27+
return {
28+
code: "UNKNOWN_ERROR",
29+
} as const;
30+
}
31+
return e;
32+
});
33+
```
34+
35+
The possible `Error` type when running this function will be
36+
37+
```ts
38+
type Res =
39+
| {
40+
code: "UNKNOWN_ERROR";
41+
}
42+
| {
43+
code: "INPUT_PARSING";
44+
cause: ...;
45+
}
46+
| { code: "UNCAUGHT_ERROR"; cause: ... };
47+
```

apps/docs/content/docs/index.mdx

+10-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,16 @@ type res = ResultAsync<
109109
| { code: "NOT_AUTHORIZED" }
110110
| {
111111
code: "INPUT_PARSING";
112-
cause: z.ZodError<{ title: string; description: string }>;
112+
cause: {
113+
formattedError: z.ZodFormattedError<{
114+
title: string;
115+
description: string;
116+
}>;
117+
flattenedError: z.typeToFlattenedError<{
118+
title: string;
119+
description: string;
120+
}>;
121+
};
113122
}
114123
>;
115124
```

apps/docs/content/docs/run/return-type.mdx

+1-62
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,6 @@ A union that can contain the following errors:
2020

2121
### Input parsing
2222

23-
When using `.run()`
24-
25-
```ts
26-
type E = {
27-
code: "INPUT_PARSING";
28-
cause: z.ZodError<T>;
29-
};
30-
```
31-
32-
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
33-
3423
```ts
3524
type E = {
3625
code: "INPUT_PARSING";
@@ -92,17 +81,6 @@ type E = {
9281

9382
### Output parsing
9483

95-
When using `.run()`
96-
97-
```ts
98-
type E = {
99-
code: "OUTPUT_PARSING";
100-
cause: z.ZodError<T>;
101-
};
102-
```
103-
104-
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
105-
10684
```ts
10785
type E = {
10886
code: "OUTPUT_PARSING";
@@ -175,46 +153,7 @@ const child = createSafeFn()
175153
});
176154
```
177155

178-
The return type of `child.run()` will be:
179-
180-
```ts
181-
type Res = ResultAsync<
182-
{
183-
childOut: string;
184-
},
185-
// Merged error from parent and child
186-
| {
187-
code: "INPUT_PARSING";
188-
cause: z.ZodError<{
189-
parentIn: string;
190-
childIn: string;
191-
}>;
192-
}
193-
// Yielded error in parent
194-
| {
195-
code: "TOO_LOW!";
196-
}
197-
// Parent did not specify a catch handler, so default is used
198-
| {
199-
code: "UNCAUGHT_ERROR";
200-
cause: "An uncaught error occurred. You can implement a custom error handler by using `catch()`";
201-
}
202-
// Specified in child catch handler
203-
| {
204-
code: "Woops!";
205-
}
206-
// Output parsing error
207-
| {
208-
code: "OUTPUT_PARSING";
209-
cause: z.ZodError<{
210-
parentOut: string;
211-
childOut: string;
212-
}>;
213-
}
214-
>;
215-
```
216-
217-
The result of calling `child.createAction()` through the `useServerAction()` hook will be:
156+
The return type of `child.run()` or calling `child.createAction()` through the `useServerAction()` hook will be:
218157

219158
```ts
220159
type Res = ResultAsync<

0 commit comments

Comments
 (0)