当使用错误的凭据登录时,会像预期的那样抛出Exception.然而,catch block未能赶上Exception,导致坠机.

发生异常.FirebaseAuthExcept ([firebase_auth/invalid-credential]提供的auth凭据是 不正确、格式错误或已过期.)

void signInWithEmail(String email, String password) async {
  state = state.copyWith(isLoading: true);
  try {
    UserCredential result = await _auth.signInWithEmailAndPassword(email: email.trim(), password: password.trim());
    state = state.copyWith(user: await _createMyUserFromFirebaseUser(result.user!), isLoading: false);
  } on FirebaseAuthException catch (e) {
    state = state.copyWith(isLoading: false, error: e.toString());
  } on PlatformException catch (_) {} catch (_) {}
}

我发现其他提到了这个问题,但从未找到过解决方案.正如您所看到的,我try 指定要捕获的异常,但不知何故,它从未被捕获.

推荐答案

我创建了一个例子来展示might会发生什么:

typedef State = ({String userName, bool isLoading, String error});

State state = (userName: 'not set', isLoading: true, error: 'nothing');

void signInWithEmail({
  required String email,
  required String password,
  Function? errorCallback,
}) async {
  if (errorCallback == null) {
    final userName = await Future.delayed(Duration.zero, () => 'Nick2001');
    state = (userName: userName, isLoading: false, error: 'nothing');
  } else {
    throw errorCallback();
  }
}

void main() async {
  try {
    signInWithEmail(
      email: 'a@b.com',
      password: '1234',
      errorCallback: () => 'User not registered.',
    );
    print(state);
  } catch (e) {
    print('Caught error in main:');
    print('  $e');
  }
}

尽管catch块已设置为捕获每个可能的异常,但该程序仍会生成以下控制台输出.

$ dart main.dart
State: (error: nothing, isLoading: true, userName: not set)
Unhandled exception:
Exception: User not registered.
#0      signInWithEmail (file:///work/main.dart:14:5)
#1      main (file:///work/main.dart:20:5)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

现在我们将函数signInWithEmail的签名更改为返回Future<void>并在main中等待该函数:

Future<void> signInWithEmail({
  required String email,
  required String password,
  Function? errorCallback,
}) async {
  if (errorCallback == null) {
    final userName = await Future.delayed(Duration.zero, () => 'Nick2001');
    state = (userName: userName, isLoading: false, error: 'nothing');
  } else {
    throw errorCallback();
  }
}

void main() async {
  try {
    await signInWithEmail(
      email: 'a@b.com',
      password: '1234',
      errorCallback: () => Exception('User not registered.'),
    );
    print('State: $state');
  } catch (e) {
    print('Caught error in main:');
    print('  $e');
  }
}

运行此程序会产生预期的输出:

Caught error in main:
  Exception: User not registered.

有关详细解释,请参阅Handling errors in void Dart function marked async. 简而言之:标记为"spec"的函数中引发的错误是future 错误.如果该函数在try-catch块中等待为not,那么在同步执行的try-catch块完成后将抛出future 错误,因此不会被捕获.

Flutter相关问答推荐

我可以在iOS设备上使用Ffltter实现Google Pay按钮吗?

将目标平台设置为Flutter 构建

在fltter_widget_from_html中启动url

Flutter 动画列表一次构建所有项目,而不是仅构建可见的项目

Flutter creating Constant.dart InputDecoration section put pass in hintText

Flutter 应用程序中的Firebase实时数据库中的orderByChild()不适用于我

BlocBuilder仅生成一次,并在后续发出时停止重建

来自FirebaseAuth的错误DisplayName和邮箱在Flutter应用程序中给出错误

Firebase WHERE过滤器在日期字段中不起作用

使用 Firebase Realtime 实现高效流式传输

Flutter 构建 Web 分段故障 - 无法启动事件处理程序线程

Firestore 使用 Flutter 以奇怪的格式保存数据

Flutter 分析发现 Gitlab CI/CD 管道中的问题,但它在本地没有

如何(部分)更新 riverpod 中的 AsyncValue?

如何更改中心的圆形进度指示器

改变步进器的线条 colored颜色 Flutter

出现错误;运算符[]不是为对象类型定义的?功能()'

Positioned 的宽度或 SizedBox 的宽度都不适用于堆栈小部件 - Flutter

如何按键在 map 列表中搜索

FLUTTER+SQL:在 ListViewBuilder 中显示数据库中的数据