Skip to content

Instantly share code, notes, and snippets.

@bobbyecho
Last active November 3, 2023 19:07
Show Gist options
  • Save bobbyecho/dce14544d6f8f7181d68689a40c46f57 to your computer and use it in GitHub Desktop.
Save bobbyecho/dce14544d6f8f7181d68689a40c46f57 to your computer and use it in GitHub Desktop.
(safeTask) error handling like golang in JS
type ErrorWithMessage = {
message: string;
};
function isErrorWithMessage(error: unknown): error is ErrorWithMessage {
return (
typeof error === 'object' &&
error !== null &&
'message' in error &&
typeof (error as Record<string, unknown>).message === 'string'
);
}
function toErrorWithMessage(maybeError: unknown): ErrorWithMessage {
if (isErrorWithMessage(maybeError)) return maybeError;
try {
if (typeof maybeError === 'string') return new Error(maybeError.toString());
return new Error(JSON.stringify(maybeError));
} catch {
// fallback in case there's an error stringifying the maybeError
// like with circular references for example.
return new Error(String(maybeError));
}
}
function getErrorMessage(error: unknown) {
return toErrorWithMessage(error).message;
}
export function safeTask<T = any>(operation: () => T): [T, null] | [null, string] {
try {
const result = operation();
return [result, null] as [T, null];
} catch (e) {
return [null, getErrorMessage(e)] as [null, string];
}
}
export async function safeAsyncTask<T = any>(operation: () => Promise<T>): Promise<[T, null] | [null, string]> {
try {
const asyncResult = await operation();
return [asyncResult, null];
} catch (e) {
return [null, getErrorMessage(e)];
}
}
export async function safeAsyncTaskW<T, R>(operation: () => Promise<T>): Promise<[T, null] | [null, R]> {
try {
const asyncResult = await operation();
return [asyncResult, null] as [T, null];
} catch (e) {
return [null, e] as [null, R];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment