Use AsyncValue.guard em vez de try/catch dentro de suas subclasses StateNotifier

Tempo de leitura: < 1 minute

Ao escrever suas próprias subclasses StateNotifier, é bastante comum usar blocos try/catch para lidar com Futures que podem falhar:

class SignOutButtonController extends StateNotifier<AsyncValue> {
  SignOutButtonController({required this.authRepository})
      : super(const AsyncValue.data(null));
  final AuthRepository authRepository;

  Future<void> signOut() async {
    try {
      state = const AsyncValue.loading();
      await authRepository.signOut(); // esse futuro pode falhar
      state = const AsyncValue.data(null);
    } catch (e) {
      state = AsyncValue.error(e);
    }
  }
}

Nesses casos, AsyncValue.guard é uma alternativa conveniente que faz todo o trabalho pesado para nós:

Future<void> signOut() async {
  state = const AsyncValue.loading();
  state = await AsyncValue.guard(() => authRepository.signOut());
}

Veja como esse método é implementado na classe AsyncValue:

abstract class AsyncValue<T> {
  static Future<AsyncValue<T>> guard<T>(Future<T> Function() future) async {
    try {
      return AsyncValue.data(await future());
    } catch (err, stack) {
      return AsyncValue.error(err, stackTrace: stack);
    }
  }

Saiba mais aqui: Método AsyncValue.guard().