···11+/**
22+ * Wraps a promise in a try/catch block and returns a Result object representing
33+ * either a successful value or an error.
44+ *
55+ * This utility function provides a more structured way to handle asynchronous operations
66+ * without using try/catch blocks throughout your codebase. It follows a pattern similar
77+ * to Rust's Result type, allowing for more predictable error handling.
88+ *
99+ * @template T - The type of the value returned by the promise on success
1010+ * @template E - The type of the error object (defaults to Error)
1111+ *
1212+ * @param promise - The promise to wrap and execute
1313+ *
1414+ * @returns A Promise resolving to a discriminated union object with:
1515+ * - On success: `{ success: true, value: T, error: null }`
1616+ * - On failure: `{ success: false, value: null, error: E }`
1717+ *
1818+ * @example
1919+ * // Success case
2020+ * const successResult = await tryCatch(Promise.resolve('data'));
2121+ * if (successResult.success) {
2222+ * console.log(successResult.value); // 'data'
2323+ * }
2424+ *
2525+ * @example
2626+ * // Error case
2727+ * const errorResult = await tryCatch(Promise.reject(new Error('Failed')));
2828+ * if (!errorResult.success) {
2929+ * console.error(errorResult.error.message); // 'Failed'
3030+ * }
3131+ *
3232+ * @example
3333+ * // Using with custom error type
3434+ * interface ApiError { code: number; message: string }
3535+ * const apiCall = tryCatch<UserData, ApiError>(fetchUserData());
3636+ */
3737+export async function tryCatch<T, E = Error>(
3838+ promise: Promise<T>,
3939+): Promise<
4040+ | {
4141+ success: true
4242+ value: T
4343+ error: null
4444+ }
4545+ | {
4646+ success: false
4747+ value: null
4848+ error: E
4949+ }
5050+> {
5151+ try {
5252+ const value = await promise
5353+ return { success: true, value, error: null }
5454+ } catch (error) {
5555+ return { success: false, value: null, error: error as E }
5656+ }
5757+}