Skip to content

Instantly share code, notes, and snippets.

@fredericoo
Last active June 24, 2025 15:41
Show Gist options
  • Save fredericoo/985cec41ddfbe62b4b65d8e14a581b33 to your computer and use it in GitHub Desktop.
Save fredericoo/985cec41ddfbe62b4b65d8e14a581b33 to your computer and use it in GitHub Desktop.
result
export class UnhandledError extends Error {
originalError: unknown;
constructor(originalError: unknown) {
super('Unhandled error');
this.originalError = originalError;
this.name = 'UnhandledError';
}
}
type AttemptSuccess<T> = readonly [null, T];
type AttemptFailure<E> = readonly [E, null];
type AttemptResult<E, T> = AttemptSuccess<T> | AttemptFailure<E>;
export type AttemptResultAsync<E, T> = Promise<AttemptResult<E, Awaited<T>>>;
export const result = {
fn: <const E, const R>(fn: (...args: any) => AttemptResult<E, R>): AttemptResult<E | UnhandledError, R> => {
try {
return fn();
} catch (error) {
return result.err(new UnhandledError(error));
}
},
fnAsync: async <const E, const R>(
fn: (...args: any) => AttemptResultAsync<E, R>,
): AttemptResultAsync<E | UnhandledError, R> => {
try {
return await fn();
} catch (error) {
return Promise.resolve(result.err(new UnhandledError(error)));
}
},
ok: <const R>(success: R): AttemptSuccess<R> => [null, success],
err: <const E>(error: E): AttemptFailure<E> => [error, null],
};
/** Examples */
const [error, data] = result.fn((a: number, b: number) => {
if (b === 0) return result.err('Cannot divide by zero');
return result.ok(a / b);
});
if (error) {
console.log('you got', error);
// ^? "Cannot divide by zero" | UnhandledError
if (error instanceof UnhandledError) {
console.log('something really unexpected happened');
} else {
console.log('couldnt divide because', error);
// ^? "Cannot divide by zero"
}
} else {
console.log('you got', data);
// ^? number
}
const [error2, data2] = await result.fnAsync(async (a: number, b: number) => {
if (b === 0) return result.err('Cannot divide by zero');
return result.ok(a / b);
});
if (error2) {
console.log('you got', error2);
// ^? "Cannot divide by zero" | UnhandledError
} else {
console.log('you got', data2);
// ^? number
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment