Skip to content

Commit 5d224b4

Browse files
nekomeowwwkwaa
andauthored
feat(std): add try-catch (#15)
* feat(std): added without-throw * refactor: improve * refactor: simplify structure, unknown by default * refactor: rename to `try-catch` --------- Co-authored-by: 藍+85CD <50108258+kwaa@users.noreply.github.com>
1 parent 6a7743e commit 5d224b4

4 files changed

Lines changed: 69 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: Try Catch
3+
description: Convert throwing functions into data/error objects.
4+
---
5+
6+
## tryCatch
7+
8+
```ts twoslash
9+
import { tryCatch } from '@moeru/std/try-catch'
10+
11+
const parseJSON = (text: string) => JSON.parse(text)
12+
13+
const { data, error } = tryCatch(() => parseJSON('{"hello":"world"}'))
14+
15+
if (error)
16+
console.error('Failed to parse JSON', error)
17+
else
18+
console.log(data.hello)
19+
```
20+
21+
## tryCatchAsync
22+
23+
```ts twoslash
24+
import { tryCatchAsync } from '@moeru/std/try-catch'
25+
26+
const fetchJSON = async (url: string) => {
27+
const res = await fetch(url)
28+
if (!res.ok)
29+
throw new Error(res.statusText)
30+
return res.json()
31+
}
32+
33+
const { data, error } = await tryCatchAsync(() => fetchJSON('https://example.com/data.json'))
34+
35+
if (error)
36+
console.error('Request failed', error)
37+
else
38+
console.log(data)
39+
```
40+
41+
## Remarks
42+
43+
This wrapper keeps your call sites non-throwing and therefore easier to compose. It is a lightweight alternative to result libraries—if you need richer ergonomics (matching, chaining, etc.) consider adopting a full Result/Try monad.

packages/std/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"./set-interval": "./src/set-interval/index.ts",
2323
"./sleep": "./src/sleep/index.ts",
2424
"./trampoline": "./src/trampoline/index.ts",
25+
"./try-catch": "./src/try-catch/index.ts",
2526
"./with-retry": "./src/with-retry/index.ts"
2627
},
2728
"files": [

packages/std/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export * from './merge'
55
export * from './set-interval'
66
export * from './sleep'
77
export * from './trampoline'
8+
export * from './try-catch'
89
export * from './with-retry'
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export type TryCatchResult<T> = { data: T, error: undefined } | { data: undefined, error: unknown }
2+
3+
/** @see {@link https://std.moeru.ai/docs/packages/std/utils/without-throw} */
4+
export const tryCatch = <
5+
T extends () => unknown,
6+
>(fn: T): TryCatchResult<ReturnType<T>> => {
7+
try {
8+
return { data: fn() as ReturnType<T>, error: undefined }
9+
}
10+
catch (error) {
11+
return { data: undefined, error }
12+
}
13+
}
14+
15+
export const tryCatchAsync = async <
16+
T extends () => Promise<unknown>,
17+
>(fn: T): Promise<TryCatchResult<Awaited<ReturnType<T>>>> => {
18+
try {
19+
return { data: await fn() as Awaited<ReturnType<T>>, error: undefined }
20+
}
21+
catch (error) {
22+
return { data: undefined, error }
23+
}
24+
}

0 commit comments

Comments
 (0)