Result of async task

Return result of async task

Async task는 두 가지 state를 가진다. Success or failure. async task의 failure는 Exception 형태로 나타나게 되어서 catch statement를 통해서 이를 handling할 수 있다.

하지만 Async task 마다 try - catch statement를 사용한다면 코드가 verbose해질 수 있다. 이는 코드의 가독성을 떨어트리고 management 를 어렵게 한다.

따라서 Async task의 결과를 리턴함으로써 caller에게 handling을 맡길 수 있다.

Option 1. Return Result instance

Async task의 result 클래스를 만들어 이 클래스의 인스턴스를 리턴한다.

class AuthResult {
  final User? user;
  final String? error;

  AuthResult({this.user, this.error});
}

  // Create user . returns user instance and exception if any
  static Future<AuthResult> createUserWithEmailandPassword({
    required String email,
    required String password,
  }) async {
    try {
      final UserCredential crendential = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      return AuthResult(user: crendential.user);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-assword') {
        return AuthResult(error: 'The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        return AuthResult(error: 'The account already exists for that email.');
      }
      return AuthResult(error: 'An error occurred while processing the request.');
    } catch (e) {
      return AuthResult(error: 'An error occurred while processing the request.');
    }
  }

caller는 catch statement대신 다음과 같이 에러 핸들링을 할 수 있다.

final result = await AuthService.createUserWithEmailandPassword(email: email, password: password)

if (result.error !== null) {
  // Show error UI
}

if (result.user !== null) {
  // handle success
}

Option 2. Multiple return and pattern matching

클래스를 만드는 것 대신, Dart의 multiple return과 pattern matching을 활용한다.

  static Future<(User? user, String? error)> createUserWithEmailandPassword({
    required String email,
    required String password,
  }) async {
    try {
      final UserCredential crendential = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      return (crendential.user, null);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-assword') {
        return (null, 'The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        return (null, 'The account already exists for that email.');
      }
      return (null, 'An error occurred while processing the request.');
    } catch (e) {
      return (null, 'An error occurred while processing the request.');
    }
  }
final (user, error) = await AuthService.createUserWithEmailandPassword(email: email, password: password)

if (error != null) {}

if (user != null) {}