处理 http 请求时出错导致颤动

Error handling an http request result in flutter

我正在尝试处理登录时给出的错误,以通过 http 请求检查用户和密码是否正确,问题是即使我处理了错误它仍然进入欢迎屏幕,因为我的检查方法总是以 true 结束,因为我在处理信息时出错 incorrectly.I 希望用户能够看到错误,但我的代码只显示异常。 https://dart.dev/guides/libraries/futures-error-handling 我看了这里,但是针对我的具体情况我没有找到答案。

prefix0.Error err = prefix0.Error();
  Future<bool> check(User user) async {
    final userResponse = await ApiClient.signIn(user).catchError((error) {
      //TODO: handle errors
      err.message = jsonDecode(error.toString())["message"];
      throw("some arbitrary error");
    });
    // TODO: Guardar el token en sharedpreferences y verificar si se logro

    return true;
  }

我真的只是想向用户展示他的错误是什么而不是我自己(这意味着 throw 将不起作用,因为它只是停止代码,将其删除只会使 return true 永远是 true.

你不应该 return 最后一行的值。你应该 return 只有当 Future 以一个值完成时才应该为真,即 return 在 .then() 回调中为真,如下所示:

Future<bool> check(User user) async {
final userResponse = await ApiClient.signIn(user)
    .then((value){
        // TODO: handle value
        return true;
    })
    .catchError((error) {
      //TODO: handle errors
      err.message = jsonDecode(error.toString())["message"];
      throw("some arbitrary error");
    });
    return false;
}

有两种方法可以处理这个问题。首先,让异常冒泡到屏幕代码中调用网络方法的位置。用 try/catch 包围该位置以捕获异常并在那里处理它:

// Network Class
Future check(User user) async {
  final userResponse = await ApiClient.signIn(user);
  // TODO: Guardar el token en sharedpreferences y verificar si se logro

  return userResponse;
}

// Screen Class
void someMethod() async {
  ...
  try {
    final userResponse = Network.check(userData);
    // TODO: Handle the user response
  } catch (e) {
    String errorMessage = e.toString();
    // TODO: Do something with the error message, such as show a snackbar:
    Scaffold.of(context).showSnackbar(Snackbar(
      content: Text(errorMessage),
    ));
  }
}

另一种是 UserResponse class 包含响应数据,并在响应不成功时显示错误状态。然后屏幕代码可以检测到此状态并做出适当的响应:

// Network Class
Future<UserResponse> check(User user) async {
  final userResponse = await ApiClient.signIn(user)
      .then((data) => UserResponse.fromNetworkResponse(data))
      .catchError((error) => UserResponse.fromError(error));

  // TODO: Guardar el token en sharedpreferences y verificar si se logro

  return userResponse;
}

// Screen Class
void someMethod() async {
  ...
  final userResponse = Network.check(userData);
  if (userResponse.hasError) {
    String errorMessage = userResponse.errorMessage;
    // TODO: Do something with the error message, such as show a snackbar:
    Scaffold.of(context).showSnackbar(Snackbar(
      content: Text(errorMessage),
    ));
  } else {
    // TODO: Handle the user response
  }
}

第二种方法需要一些设置,但它是最灵活的,不需要您依赖 try/catch 来运行。