我如何 return 来自 dart 中的 Future 的错误?

How do I return error from a Future in dart?

在我的 flutter 应用程序中,我有一个处理 http 请求和 returns 解码数据的未来。但是,如果 status code != 200 可以通过 .catchError() 处理程序获得,我希望能够发送错误。

这是未来:

Future<List> getEvents(String customerID) async {
  var response = await http.get(
    Uri.encodeFull(...)
  );

  if (response.statusCode == 200){
    return jsonDecode(response.body);
  }else{
    // I want to return error here 
  }
}

当我调用这个函数时,我希望能够得到如下错误:

getEvents(customerID)
.then(
  ...
).catchError(
  (error) => print(error)
);

您可以使用 throw :

Future<List> getEvents(String customerID) async {
  var response = await http.get(
    Uri.encodeFull(...)
  );

  if (response.statusCode == 200){
    return jsonDecode(response.body);
  }else{
    // I want to return error here 
       throw("some arbitrary error"); // error thrown
  }
}

投掷 error/exception:

您可以使用 returnthrow 来抛出错误或异常。

  • 使用return:
    Future<void> foo() async {
      if (someCondition) {
        return Future.error('FooError');
      }
    }
    
  • 使用throw:
    Future<void> bar() async {
      if (someCondition) {
        throw Exception('BarException');
      }
    }
    

赶上 error/exception:

您可以使用 catchErrortry-catch 块来捕获错误或异常。

  • 使用catchError:
    foo().catchError(print);
    
  • 使用try-catch:
    try {
      await bar();
    } catch (e) {
      print(e);
    }
    

//POST

Future<String> post_firebase_async({String? path , required Product product}) async {
    final Uri _url = path == null ? currentUrl: Uri.https(_baseUrl, '/$path');

    print('Sending a POST request at $_url');

    final response = await http.post(_url, body: jsonEncode(product.toJson()));
    if(response.statusCode == 200){
      final result = jsonDecode(response.body) as Map<String,dynamic>;
      return result['name'];
    }
    else{
      //throw HttpException(message: 'Failed with ${response.statusCode}');
      return Future.error("This is the error", StackTrace.fromString("This is its trace"));
    }

  }

调用方法如下:

  final result = await _firebase.post_firebase_async(product: dummyProduct).
  catchError((err){
    print('huhu $err');
  });

如果 whenComplete() 的回调抛出错误,则 whenComplete() 的 Future 完成并出现该错误:

void main() {
  funcThatThrows()
      // Future completes with a value:
      .catchError(handleError)
      // Future completes with an error:
      .whenComplete(() => throw Exception('New error'))
      // Error is handled:
      .catchError(handleError);
}

解决这个问题的另一种方法是使用 dartz 包。

如何使用它的示例类似于这样

import 'package:dartz/dartz.dart';

abstract class Failure {}
class ServerFailure extends Failure {}
class ResultFailure extends Failure {
  final int statusCode;
  const ResultFailure({required this.statusCode});
}

FutureOr<Either<Failure, List>> getEvents(String customerID) async {
  try {
    final response = await http.get(
      Uri.encodeFull(...)
    );

    if (response.statusCode == 200) {
      return Right(jsonDecode(response.body));
    } else {
      return Left(ResultFailure(statusCode: response.statusCode)); 
    }
  }
  catch (e) {
    return Left(ServerFailure());  
  }
}

main() async {
  final result = await getEvents('customerId');
  result.fold(
    (l) => print('Some failure occurred'),
    (r) => print('Success')
  );
}