-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtyped-errors.ts
More file actions
38 lines (35 loc) · 1.22 KB
/
Copy pathtyped-errors.ts
File metadata and controls
38 lines (35 loc) · 1.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* Typed error responses: declare error schemas per status, return them with
* c.error() (payload type-checked!), and the client narrows by status.
*
* bun run examples/typed-errors.ts
*/
import { Ma, mc } from "@ma/core"
import { z } from "zod"
const app = new Ma().get(
"/users/:id",
{
response: z.object({ id: z.string(), name: z.string() }),
errors: {
404: z.object({ message: z.string() }),
403: z.object({ message: z.string(), requiredRole: z.string() }),
},
},
(c) => {
if (c.params.id === "0") return c.error(404, { message: "no such user" })
if (c.params.id === "1") return c.error(403, { message: "forbidden", requiredRole: "admin" })
return { id: c.params.id, name: "Alice" }
},
)
// mc(app) is the in-process test client — no server needed.
const client = mc(app)
for (const id of ["42", "0", "1"]) {
const res = await client.users[":id"].get({ id })
if (res.ok) {
console.log(`ok: ${res.data.name}`) // data: { id: string; name: string }
} else if (res.status === 404) {
console.log(`404: ${res.data.message}`) // data: { message: string }
} else {
console.log(`403: needs ${res.data.requiredRole}`) // data: { message: string; requiredRole: string }
}
}