Skip to content

Instantly share code, notes, and snippets.

@lorens-osman-dev
Created April 4, 2025 19:08
Show Gist options
  • Save lorens-osman-dev/15f223fbe7e745c23f2cfb6696829ec4 to your computer and use it in GitHub Desktop.
Save lorens-osman-dev/15f223fbe7e745c23f2cfb6696829ec4 to your computer and use it in GitHub Desktop.
/**
* Type alias for a promise of type T.
*/
type ToIn<T> = Promise<T>;
/**
* Type alias for a function that can optionally be executed after the promise resolves or rejects.
* It can return void or a Promise that resolves to void.
*/
type ToFinally = () => void | Promise<void>;
/**
* Wraps a promise to handle its resolution and rejection with standardized error handling.
*
* @template $Promise - The type of the promise's resolved value.
* @param {ToIn<$Promise>} promise - The input promise or value to handle.
* @param {ToFinally} [_finally] - An optional callback to execute in the finally block.
* @returns {Promise<{ result: $Promise | null; error: Error | null }>}
* A promise that resolves to an object containing either the result or an error.
*
* @example
* // Usage with an async function
* async function example() {
* const { result, error } = await to(fetchData());
* if (error) {
* console.error('Error fetching data:', error);
* } else {
* console.log('Data fetched successfully:', result);
* }
* }
*
* @example
* // Usage with a finally callback
* async function example() {
* const { result, error } = await to(fetchData(), () => {
* console.log('Cleanup after fetch');
* });
* if (error) {
* console.error('Error fetching data:', error);
* } else {
* console.log('Data fetched successfully:', result);
* }
* }
*/
export default async function to<$Promise>(
promise: ToIn<$Promise>,
_finally?: ToFinally,
): Promise<{ result: $Promise | null; error: Error | null }> {
try {
// Await the result of the input promise.
const result = await promise;
// Return a tuple with null error and the result.
return { result: result, error: null };
} catch (error) {
// If the error is an instance of Error, return it with null result.
if (error instanceof Error) {
return { result: null, error: error };
}
// For non-Error reject values, return a generic Error with a descriptive message.
const err = new Error(typeof error === "string" ? error : "non-supported reject value");
return { result: null, error: err };
} finally {
// If a finally callback is provided, await its execution.
if (_finally) await _finally();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment