diff --git a/lib/src/either.dart b/lib/src/either.dart index 2ee5b58..774f814 100644 --- a/lib/src/either.dart +++ b/lib/src/either.dart @@ -213,6 +213,14 @@ Either catching(Function0 thunk) { } } +Future> catchAsync(Function0> f) async { + try { + return right(await f()); + } catch (e) { + return left(e); + } +} + class EitherMonad extends MonadOpsMonad> { EitherMonad(): super(right); } diff --git a/test/either_test.dart b/test/either_test.dart index 6461710..e1be8da 100644 --- a/test/either_test.dart +++ b/test/either_test.dart @@ -103,4 +103,28 @@ void main() { expect(right.value, 2); }); }); + + group("catchAsync", () { + test("successful future", () async { + expect(await catchAsync(() => Future.value(2)), right(2)); + }); + + test("failed future", () async { + final error = Exception("foobar"); + expect(await catchAsync(() => Future.error(error)), left(error)); + }); + + test("throwing synchronous function body", () async { + final error = Exception("foobar"); + expect(await catchAsync(() => throw error), left(error)); + }); + + test("value from async function", () async { + expect(await catchAsync(() async => 2), right(2)); + }); + + test("value from sync function", () async { + expect(await catchAsync(() => 2), right(2)); + }); + }); }