-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
110 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
--- | ||
title: Handler functions | ||
--- | ||
|
||
### Handler | ||
|
||
`handler()` takes in a function that will be called when your SafeFn is executed. This function should return a `Result<TData,TError>` or `Promise<Result<TData,TError>>`. | ||
If you set an output schema, the `TData` type is constrained to the parsed output type of your schema. Otherwise, you can return any `Result` type. | ||
|
||
The returned types from `run()` and `createAction()()` are updated with the inferred return type of your handler function. | ||
|
||
```ts | ||
const mySafeFunction = SafeFn.new() | ||
.unparsedInput<{ firstName: string; lastName: string }>() | ||
.output(z.object({ fullName: z.string() })) | ||
.handler((args) => { | ||
// Error: Type Ok<{ name: string; }> is not assignable to type Ok<{ fullName: string; }> // [!code highlight] | ||
return ok({ | ||
fullName: `${args.unparsedInput.firstName} ${args.unparsedInput.lastName}`, | ||
}); | ||
}); | ||
``` | ||
|
||
the following arguments are passed to the handler function: | ||
|
||
- `args.parsedInput`: The result of parsing the input schema. | ||
- `args.unparsedInput`: The unparsed input of your function. | ||
- `args.ctx`: The `Ok` return value of the parent handler function or undefined if no parent handler function is set. | ||
|
||
### Safe Handler | ||
|
||
Instead of using `handler()`, you can also use `safeHandler()`. This offers the same functionality as NeverThrow's `safeTry()` and requires an async generation function. | ||
This is probably the route you want to take if the rest of your codebase is built with NeverThrow, as it allows ergonomic "return if error" handling. | ||
|
||
Consider the following example: | ||
|
||
```ts | ||
// Fake function declarations | ||
declare function getUserTodoList(): ResultAsync<string[], { code: "DB_ERROR" }>; | ||
declare function getTodoById( | ||
id: string, | ||
): ResultAsync< | ||
{ id: string; title: string; description: string }, | ||
{ code: "DB_ERROR" } | ||
>; | ||
|
||
const getLastUserTodoTitle = SafeFn.new().handler(async () => { | ||
const todoList = await getUserTodoList(); | ||
if (todoList.isErr()) { | ||
return todoList; | ||
} | ||
if (!todoList.value.length) { | ||
return err({ | ||
code: "NO_TODOS", | ||
}); | ||
} | ||
const lastTodoId = todoList.value[todoList.value.length - 1]; | ||
const todo = await getTodoById(lastTodoId); | ||
if (todo.isErr()) { | ||
return todo; | ||
} | ||
return ok(todo.value.title); | ||
}); | ||
``` | ||
|
||
This can be rewritten using `safeHandler()` as follows: | ||
|
||
```ts | ||
// Fake function declarations | ||
declare function getUserTodoList(): ResultAsync<string[], { code: "DB_ERROR" }>; | ||
declare function getTodoById( | ||
id: string, | ||
): ResultAsync< | ||
{ id: string; title: string; description: string }, | ||
{ code: "DB_ERROR" } | ||
>; | ||
|
||
const getLastUserTodoTitle = SafeFn.new().handler(async function* () { | ||
const todoList = yield* getUserTodoList().safeUnwrap(); | ||
if (!todoList.length) { | ||
return err({ | ||
code: "NO_TODOS", | ||
}); | ||
} | ||
const lastTodoId = todoList[todoList.length - 1]; | ||
const todo = yield* getTodoById(lastTodoId).safeUnwrap(); | ||
return ok(todo.title); | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
title: Instantiate | ||
--- | ||
|
||
## Instantiating | ||
|
||
{/* TODO: chaining page */} | ||
You can create a SafeFn by using the `.new()` method. Here you can optionally pass in a parent handler (see chaining) | ||
|
||
```ts | ||
import { parentFunction } from "./some-file"; | ||
|
||
const myySafeFunction = SafeFn.new(); | ||
const mySafeFunction2 = SafeFn.new(parentFunction); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"title": "Creating a SafeFn", | ||
"pages": ["instantiate", "input-output", "handler"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
title: Hello World | ||
title: Hello World! | ||
description: Your first document | ||
--- | ||
|
||
|