Add try-async method
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
export * from './event-emitter.ts';
|
export * from './event-emitter.ts';
|
||||||
export * from './exponential-backoff.ts';
|
export * from './exponential-backoff.ts';
|
||||||
export * from './extended-json.ts';
|
export * from './extended-json.ts';
|
||||||
|
export * from './misc.ts';
|
||||||
export * from './script.ts';
|
export * from './script.ts';
|
||||||
export * from './sse-session/index.ts';
|
export * from './sse-session/index.ts';
|
||||||
export * from './template/errors.ts';
|
export * from './template/errors.ts';
|
||||||
|
|||||||
15
source/misc.ts
Normal file
15
source/misc.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Tries to execute an async function and handles any errors that occur.
|
||||||
|
* @param fn - The function to execute.
|
||||||
|
* @param onError - The callback to call if the function fails.
|
||||||
|
* @returns The result of the function.
|
||||||
|
*/
|
||||||
|
export const tryAsync = async (fn: () => unknown, onError?: (error: Error) => void): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await fn();
|
||||||
|
} catch (error) {
|
||||||
|
const errorInstance = error instanceof Error ? error : new Error(`${error}`);
|
||||||
|
|
||||||
|
onError?.(errorInstance);
|
||||||
|
}
|
||||||
|
};
|
||||||
70
test/misc.test.ts
Normal file
70
test/misc.test.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { expect, test, vi } from 'vitest';
|
||||||
|
import { tryAsync } from '../source/misc.ts';
|
||||||
|
|
||||||
|
/** Spy used to confirm the wrapped async function ran successfully. */
|
||||||
|
const successFlagFn = vi.fn();
|
||||||
|
|
||||||
|
/** Spy used to confirm the error callback was invoked on failure. */
|
||||||
|
const errorFlagFn = vi.fn();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that tryAsync invokes the function and skips the error callback on success.
|
||||||
|
*/
|
||||||
|
const testTryAsyncCallsFunctionOnSuccess = async (): Promise<void> => {
|
||||||
|
// Reset spies so prior test runs do not affect call counts.
|
||||||
|
vi.clearAllMocks();
|
||||||
|
|
||||||
|
const successFn = async (): Promise<void> => {
|
||||||
|
successFlagFn();
|
||||||
|
};
|
||||||
|
|
||||||
|
await tryAsync(successFn);
|
||||||
|
|
||||||
|
// The wrapped function should run and no error handler should be called.
|
||||||
|
expect(successFlagFn).toHaveBeenCalledOnce();
|
||||||
|
expect(errorFlagFn).not.toHaveBeenCalled();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that tryAsync invokes the error callback when the function throws.
|
||||||
|
*/
|
||||||
|
const testTryAsyncCallsErrorCallbackOnFailure = async (): Promise<void> => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
|
||||||
|
const errorFn = async (): Promise<void> => {
|
||||||
|
throw new Error('test');
|
||||||
|
};
|
||||||
|
|
||||||
|
await tryAsync(errorFn, errorFlagFn);
|
||||||
|
|
||||||
|
// The success path should not run; the error callback should receive the failure.
|
||||||
|
expect(successFlagFn).not.toHaveBeenCalled();
|
||||||
|
expect(errorFlagFn).toHaveBeenCalledOnce();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that tryAsync wraps non-Error throws in Error instances before calling the error callback.
|
||||||
|
*/
|
||||||
|
const testTryAsyncConvertsNonErrorThrows = async (): Promise<void> => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
|
||||||
|
const errorFn = async (): Promise<void> => {
|
||||||
|
/* eslint-disable-next-line */
|
||||||
|
throw 'test';
|
||||||
|
};
|
||||||
|
|
||||||
|
await tryAsync(errorFn, errorFlagFn);
|
||||||
|
|
||||||
|
// Non-Error throws must be normalized to Error before onError is called.
|
||||||
|
expect(successFlagFn).not.toHaveBeenCalled();
|
||||||
|
expect(errorFlagFn).toHaveBeenCalledOnce();
|
||||||
|
expect(errorFlagFn).toHaveBeenCalledWith(new Error('test'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const runTests = async (): Promise<void> => {
|
||||||
|
test('tryAsync: calls the function and skips the error callback on success', testTryAsyncCallsFunctionOnSuccess);
|
||||||
|
test('tryAsync: calls the error callback when the function fails', testTryAsyncCallsErrorCallbackOnFailure);
|
||||||
|
test('tryAsync: converts non-Error throws to Error instances', testTryAsyncConvertsNonErrorThrows);
|
||||||
|
};
|
||||||
|
|
||||||
|
await runTests();
|
||||||
Reference in New Issue
Block a user