type Success<T> = { data: T; error: null };
type Failure<E> = { data: null; error: E };

export type Result<T, E = Error> = Success<T> | Failure<E>;

/**
 * A universal tryCatch wrapper that:
 *  - Never throws
 *  - Always resolves to Result<T,E>
 *  - Allows optional error mapping function for strong typing
 */

export async function tryCatch<T, E = Error>(
	promise: Promise<T>,
	onError?: (error: unknown) => E,
): Promise<Result<T, E>> {
	try {
		const data = await promise;
		return { data, error: null };
	} catch (err: unknown) {
		const error = onError
			? onError(err)
			: err instanceof Error
				? (err as E)
				: (new Error(String(err)) as E);
		return { data: null, error };
	}
}
