df_safer_dart 0.12.0
df_safer_dart: ^0.12.0 copied to clipboard
A package inspired by functional programming, designed to enhance the structure, safety, and debuggability of mission-critical code.
Dart & Flutter Packages by dev-cetera.com & contributors.
Summary #
This package, inspired by Rust and functional programming, aims to enhance the structure, safety and debuggability of your applications by leveraging monads and other advanced mechanisms.
Dart’s traditional error-handling approach depends on null checks, try-catch blocks, and Futures that can throw errors at any time, necessitating asynchronous error handling. This often leads to complex and unpredictable error management.
Aiming to address these challenges, this package offers safer alternatives and more predictable mechanisms.
While it introduces some boilerplate and incurs a minor performance trade-off due to safety checks, it is best suited for mission critical sections of your project where reliability and safety are essential. For less sensitive code, standard approaches like Future, FutureOr, try-catch, and nullable types may be more appropriate.
This package introduces three core monads —- Result
, Option
, and Resolvable
-- that work seamlessly together:
Result
: Encapsulates a value that is eitherOk
(success) orErr
(failure), providing a structured approach to error handling.Option
: Represents a value that is eitherSome
(present) orNone
(absent), ensuring explicit handling of nullable scenarios.Resolvable
: Unifies asynchronous and synchronous values, creating a consistent interface for both paradigms.
These monads form the foundation for more predictable, expressive, and maintainable error handling in Dart.
Additionally, the package includes two complementary mechanisms:
SafeCompleter
: A secure alternative to Dart’s Completer, leveraging the included monads to handle both synchronous and asynchronous values with built-in safety.Sequential
: A utility for executing synchronous or asynchronous code in guaranteed sequential order, simplifying the management of complex workflows.
With these tools, the package provides a solid framework for improving the reliability and readability of your Dart applications.
For a full feature set, please refer to the API reference.
Usage Example #
Example of avoiding try-catch blocks in Dart, to produce safer code:
void main() async {
// Fetch the IP address and handle both success and error results.
fetchIpAddress().flatMap(
(result) => result
.ifOk((e) {
print('IP address: ${result.unwrap()}');
})
.ifErr((e) {
print('Error: $e');
}),
);
}
Async<String> fetchIpAddress() {
// Async, Sync or Resolvable can be used to wrap
// potentially throwing code.
//
// The only rules here are:
//
// 1. ALWAYS await all asynchronous operations inside Async
// (or Resolvable) to ensure that exceptions are properly caught and
// wrapped in a Result.
//
// 2. Only deal with asynchronous operations in Async or
// Resolvable. Not in Sync.
//
// 3. You can throw any Objects within unsafe, but prefer throwing Err
// objects as it is the standard and will help with debugging.
return Async(() async {
final response = await http.get(
Uri.parse('https://api.ipify.org?format=json'),
);
// Throw an Err if the status code is not 200. Any other exceptions within
// Resolvable.wrap will be caught and wrapped in an Err.
if (response.statusCode != 200) {
throw Err('Failed to fetch IP address');
}
final data = jsonDecode(response.body);
final ip = data['ip'] as String;
return ip;
});
}
Contributing and Discussions #
This is an open-source project, and we warmly welcome contributions from everyone, regardless of experience level. Whether you're a seasoned developer or just starting out, contributing to this project is a fantastic way to learn, share your knowledge, and make a meaningful impact on the community.
Ways you can contribute #
- Buy me a coffee: If you'd like to support the project financially, consider buying me a coffee. Your support helps cover the costs of development and keeps the project growing.
- Find us on Discord: Feel free to ask questions and engage with the community here: https://discord.gg/gEQ8y2nfyX.
- Share your ideas: Every perspective matters, and your ideas can spark innovation.
- Help others: Engage with other users by offering advice, solutions, or troubleshooting assistance.
- Report bugs: Help us identify and fix issues to make the project more robust.
- Suggest improvements or new features: Your ideas can help shape the future of the project.
- Help clarify documentation: Good documentation is key to accessibility. You can make it easier for others to get started by improving or expanding our documentation.
- Write articles: Share your knowledge by writing tutorials, guides, or blog posts about your experiences with the project. It's a great way to contribute and help others learn.
No matter how you choose to contribute, your involvement is greatly appreciated and valued!
We drink a lot of coffee... #
If you're enjoying this package and find it valuable, consider showing your appreciation with a small donation. Every bit helps in supporting future development. You can donate here: https://www.buymeacoffee.com/dev_cetera
License #
This project is released under the MIT License. See LICENSE for more information.