domain_error 2.1.0 copy "domain_error: ^2.1.0" to clipboard
domain_error: ^2.1.0 copied to clipboard

Domain errors with Either, Result, and executeSafely for expected errors in Dart applications.

domain_error #

Turn thrown errors into values you can fold.

A domain error is a DomainError. An outcome is a Result<T>: Either<DomainError, T>. On a Result, domainError is the failed DomainError. A generic Either uses errValue. executeSafely and executeSafelySync run a function and return that result.

Install #

dependencies:
  domain_error: ^2.1.0

Use #

One sealed error root per feature. Set typeIdentifier yourself. It stays readable after obfuscation.

import 'dart:async';

import 'package:domain_error/domain_error.dart';

sealed class OrderError extends DomainError {
  const OrderError({super.message, super.rawError, super.stackTrace});

  @override
  String get typeIdentifier => 'OrderError';
}

final class OrderIdEmptyError extends OrderError {
  const OrderIdEmptyError();

  @override
  String get typeIdentifier => 'OrderIdEmptyError';
}

final class OrderTimeoutError extends OrderError {
  const OrderTimeoutError();

  @override
  String get typeIdentifier => 'OrderTimeoutError';
}

final class OrderUnavailableError extends OrderError {
  const OrderUnavailableError({super.rawError, super.stackTrace});

  @override
  String get typeIdentifier => 'OrderUnavailableError';
}

Catch throws. Map unexpected objects. Fold the result.

final result = await executeSafely<Order>(
  () {
    if (id.isEmpty) {
      throw const OrderIdEmptyError();
    }
    return loadOrder(id: id);
  },
  options: ExecuteSafelyOptions(
    mapRawErrorToDomain: (rawError, stackTrace) {
      if (rawError is TimeoutException) {
        return const OrderTimeoutError();
      } else {
        return OrderUnavailableError(rawError: rawError, stackTrace: stackTrace);
      }
    },
    onDomainError: (domainError, stackTrace) { /* log */ },
    onRawError: (rawError, stackTrace) { /* log */ },
  ),
);

result.fold(
  (domainError) => print(domainError.typeIdentifier),
  (successValue) => print(successValue.title),
);

final syncResult = executeSafelySync<Order>(
  () => loadOrder(id: id),
  options: ExecuteSafelySyncOptions(
    mapRawErrorToDomain: (rawError, stackTrace) {
      return OrderUnavailableError(rawError: rawError, stackTrace: stackTrace);
    },
  ),
);

If the function throws a DomainError, you get that same object. If it throws anything else, you get what mapRawErrorToDomain returns. onDomainError and onRawError only observe. They do not change the result.

Runnable sample: example/domain_error_example.dart.

License #

MIT. Issues: https://github.com/pchkauu/domain_error/issues

1
likes
0
points
180
downloads

Publisher

unverified uploader

Weekly Downloads

Domain errors with Either, Result, and executeSafely for expected errors in Dart applications.

Repository (GitHub)
View/report issues

Topics

#error-handling #domain #exceptions

License

unknown (license)

Dependencies

collection, equatable, meta

More

Packages that depend on domain_error