import { isPromise } from '../../types'; export type TryItReturn = Return extends Promise ? Promise<{ error: Error; data: undefined } | { error: undefined; data: Awaited }> : { error: Error; data: undefined } | { error: undefined; data: Return }; function onResolve(data: any) { return { error: undefined, data }; } function onReject(error: any) { return { error, data: undefined }; } /** * @name tryIt * @category Async * @description Wraps promise-based code in a try/catch block without forking the control flow * * @param {Function} fn - The function to try * @returns {Function} - The function that will return a tuple with the error and the result * * @example * const wrappedFetch = tryIt(fetch); * const { error, data } = await wrappedFetch('https://jsonplaceholder.typicode.com/todos/1'); * * @example * const { error, data } = await tryIt(fetch)('https://jsonplaceholder.typicode.com/todos/1'); * * @since 0.0.3 */ export function tryIt( fn: (...args: Args) => Return, ) { return (...args: Args): TryItReturn => { try { const result = fn(...args); if (isPromise(result)) return result.then(onResolve, onReject) as TryItReturn; return { error: undefined, data: result } as TryItReturn; } catch (error) { return { error, data: undefined } as TryItReturn; } }; }