type_result 3.0.0 type_result: ^3.0.0 copied to clipboard
type_result is a Dart package that simplifies error handling and outcome representation with the Result type. Handle errors effectively and enhance code reliability with ease using type_result.
type_result #
type_result
is a simple yet powerful Flutter package that helps manage operation results effectively. It introduces a Result
type, which can represent either a successful outcome (Success
) or an error (Failure
). This makes handling errors clean, safe, and predictable.
Installation #
To use type_result
, add it to your pubspec.yaml
file:
dependencies:
type_result: ^3.0.0
Then run:
flutter packages get
Usage #
Basics of the Result
Class #
The Result<V, E>
class is designed to handle operations that might succeed or fail. Here is an example:
Result<int, String> divide(int dividend, int divisor) {
if (divisor == 0) {
return Result.failure("Cannot divide by zero");
} else {
return Result.success(dividend ~/ divisor);
}
}
In this example:
V
represents the type of the successful result (e.g.,int
).E
represents the type of the error (e.g.,String
).
Here's how you might use the divide
function:
var result = divide(10, 2);
if (result.isSuccess) {
print('The result is ${result.success}.'); // The result is 5.
} else {
print('An error occurred: ${result.failure}.');
}
Handling Results with switch
#
The Result
type is a sealed class, which means you can use a switch
statement to handle each possible outcome:
switch (result) {
case Success(:final value):
print('The result is $value.');
case Failure(:final value):
print('An error occurred: $value.');
}
Useful Methods #
isSuccess
: Returnstrue
if the result is successful (Success
).isFailure
: Returnstrue
if the result is an error (Failure
).successOrNull
: Returns the value if successful, ornull
otherwise.failureOrNull
: Returns the error if failed, ornull
otherwise.
For example:
var result = divide(10, 0);
print(result.successOrNull); // null
print(result.failureOrNull); // "Cannot divide by zero"
If you are sure about the result type, you can directly access the value or error using success
or failure
. Note that these will throw an AssertionError
if the result is not of the expected type.
Transforming Results #
You can transform values or errors using:
mapSuccess
: Transforms the value if it'sSuccess
.mapFailure
: Transforms the error if it'sFailure
.successThen
andfailureThen
: Chain transformations and operations.
Example:
Result<int, String> result = divide(10, 2); // Success(5)
Result<String, String> stringResult = result.mapSuccess((value) => value.toString()); // Success("5")
You can also use successOr
and failureOr
to provide default values:
Result<int, String> result = divide(10, 0); // Failure("Cannot divide by zero")
print(result.successOr(0)); // 0
print(result.failureOr("No error")); // "Cannot divide by zero"
Asynchronous Support #
type_result
also works well with asynchronous operations by extending Future<Result<V, E>>
. This allows you to chain operations in a clean and readable way, and also simplifies handling with await
.
For example, instead of writing:
final userId = (await authedUserId()).successOrNull;
you can write:
final userId = await authedUserId().successOrNull;
## Benefits of Using `Result`
Using the `Result` type helps you clearly indicate whether an operation succeeded or failed. It encapsulates both the success and error scenarios, making it less likely that you'll forget to handle an error or mistakenly assume success. This leads to more predictable, maintainable, and readable code.
By using `type_result`, you can avoid common error-handling pitfalls and write safer, cleaner code.