javascript / expert
Snippet
Functional Error Handling with Result Monads
By replacing traditional try-catch blocks with a Result type, you enforce exhaustive error checking at compile time. This pattern is especially useful in Next.js Server Actions to ensure that all failure modes are explicitly handled before sending a response back to the client.
snippet.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };async function safeFetchUser(id: string): Promise<Result<User>> {try {const user = await db.users.findUnique({ where: { id } });if (!user) return { ok: false, error: new Error('User not found') };return { ok: true, value: user };} catch (e) {return { ok: false, error: e as Error };}}const response = await safeFetchUser('123');if (response.ok) { console.log(response.value); }
nextjs
Breakdown
1
type Result<T, E = Error> = ...
Defines a union type representing either a successful computation or a failure.
2
if (!user) return { ok: false, error: ... };
Explicitly returns an error state instead of throwing, making the failure part of the API contract.
3
if (response.ok) { ... }
Uses TypeScript's type narrowing to safely access the value only when the operation succeeded.