diff --git a/pkgs/async/CHANGELOG.md b/pkgs/async/CHANGELOG.md index 48a3b444..a45dc811 100644 --- a/pkgs/async/CHANGELOG.md +++ b/pkgs/async/CHANGELOG.md @@ -4,6 +4,7 @@ with variable intervals. - Mark `Result` as `sealed`, and `ValueResult`, and `ErrorResult` as `final` classes. +- Add `value` getter to `Result`. ## 2.13.1 diff --git a/pkgs/async/lib/src/result/error.dart b/pkgs/async/lib/src/result/error.dart index f17ab077..fcf3ec8d 100644 --- a/pkgs/async/lib/src/result/error.dart +++ b/pkgs/async/lib/src/result/error.dart @@ -37,6 +37,11 @@ final class ErrorResult implements Result { @override Future get asFuture => Future.error(error, stackTrace); + @override + Never get value { + Error.throwWithStackTrace(error, stackTrace); + } + /// Calls an error handler with the error and stacktrace. /// /// An async error handler function is either a function expecting two diff --git a/pkgs/async/lib/src/result/result.dart b/pkgs/async/lib/src/result/result.dart index ba436424..8407cd3c 100644 --- a/pkgs/async/lib/src/result/result.dart +++ b/pkgs/async/lib/src/result/result.dart @@ -221,6 +221,16 @@ sealed class Result { /// Calls the sink's `add` or `addError` method as appropriate. void addTo(EventSink sink); + /// The value of this result, or throws the error if this is an error result. + /// + /// If this is a [ValueResult], returns its value. + /// If this is an [ErrorResult], throws its error with its stack trace + /// using [Error.throwWithStackTrace]. + /// + /// To read the value without the risk of an exception first check [isValue] + /// or use [asValue] to get `null` instead. + T get value; + /// A future that has been completed with this result as a value or an error. Future get asFuture; } diff --git a/pkgs/async/lib/src/result/value.dart b/pkgs/async/lib/src/result/value.dart index 8b5bb106..8eb42cb1 100644 --- a/pkgs/async/lib/src/result/value.dart +++ b/pkgs/async/lib/src/result/value.dart @@ -7,6 +7,7 @@ part of 'result.dart'; /// A result representing a returned value. final class ValueResult implements Result { /// The result of a successful computation. + @override final T value; @override diff --git a/pkgs/async/test/result/result_test.dart b/pkgs/async/test/result/result_test.dart index 65d47f9c..066f2e37 100644 --- a/pkgs/async/test/result/result_test.dart +++ b/pkgs/async/test/result/result_test.dart @@ -131,6 +131,30 @@ void main() { ); }); + group('value', () { + test('returns value for ValueResult', () { + var result = Result.value(42); + expect(result.value, equals(42)); + }); + + test('throws error for ErrorResult', () { + var result = Result.error('BAD', stack); + expect(() => result.value, throwsA('BAD')); + }); + + test('throws error with stack trace for ErrorResult', () { + var result = Result.error('BAD', stack); + // Use try/catch over throwsA to check expectations about the stack trace + try { + result.value; + fail('Expected error to be thrown'); + } catch (e, s) { + expect(e, equals('BAD')); + expect(Trace.from(s).toString(), equals(stack.toString())); + } + }); + }); + test('capture future value', () { var value = Future.value(42); Result.capture(value).then(