@@ -2,17 +2,41 @@ type Success<T> = [error: null, data: T];
22type Failure < E extends Error = Error > = [ error : E , data : null ] ;
33type Result < T , E extends Error = Error > = Success < T > | Failure < E > ;
44
5+ type SyncFn < T > = ( ) => T ;
6+ type AsyncFn < T > = ( ) => Promise < T > ;
7+
8+ /**
9+ * Acceptable input types for `tryCatch`:
10+ * - A synchronous function that might throw
11+ * - An async function (returns a promise)
12+ * - A promise (e.g. from `fetch()`)
13+ */
14+ type TryCatchInput < T > = SyncFn < T > | AsyncFn < T > | Promise < T > ;
15+
516/**
6- * Wraps a promise or async function and returns a tuple [error, data].
7- * Catches both synchronous and asynchronous errors.
17+ * Wraps a potentially throwing function or a promise and returns a tuple `[error, data]`.
18+ * Catches both sync and async errors, and wraps non-Error throws into an `Error` object.
19+ *
20+ * ## Examples
21+ *
22+ * ```ts
23+ * // ✅ Synchronous function that may throw
24+ * const [err, data] = await tryCatch(() => JSON.parse("{ \"a\": 1 }"));
25+ *
26+ * // ✅ Async function
27+ * const [err, data] = await tryCatch(() => fetch("/api/data").then(r => r.json()));
28+ *
29+ * // ✅ Direct promise
30+ * const [err, data] = await tryCatch(fetch("/api/data"));
31+ * ```
832 */
933export async function tryCatch < T , E extends Error = Error > (
10- promiseOrFn : Promise < T > | ( ( ) => Promise < T > ) ,
34+ input : TryCatchInput < T > ,
1135) : Promise < Result < T , E > > {
1236 try {
13- const data = typeof promiseOrFn === "function" ? await promiseOrFn ( ) : await promiseOrFn ;
37+ const result = typeof input === "function" ? await input ( ) : await input ;
1438
15- return [ null , data ] ;
39+ return [ null , result ] ;
1640 } catch ( e ) {
1741 const error = e instanceof Error ? e : new Error ( String ( e ) , { cause : e } ) ;
1842 return [ error as E , null ] ;
0 commit comments