我不断收到这个错误
Unhandled Exception: Invalid argument(s) (onError): The error handler of Future.then must return a value of the returned future's type
NetworkApi
class NetworkApi {
NetworkApi(this.url);
final String url;
Future getData() async {
http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
return jsonDecode(data);
} else {
if (kDebugMode) {
print(response.statusCode);
}
}
}
}
ApiSelector
class ApiSelector {
Future getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
throw'Error while fetching data';
}
return MyModel.fromJson(Data);
}
}
MyFunction调用API选择器
Future getDataFromApi() async {
await _apiSelector
.getApiData(categoryName: "Some Category")
.then((value) {
myModel = value as MyModel;
print(myModel);
return value;
} ,onError: (error) {
print(error);
return error;
},);
}
我想尽一切办法来解决这个问题。请你指导我该怎么做。我甚至尝试过异常处理,但仍然出现了这个错误。
指定返回类型的Future,如Future<dynamic>
NetworkApi
class NetworkApi {
NetworkApi(this.url);
final String url;
Future<dynamic> getData() async {
http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
return jsonDecode(data);
} else {
if (kDebugMode) {
print(response.statusCode);
}
}
}
}
ApiSelector
class ApiSelector {
Future<MyModel> getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
throw'Error while fetching data';
}
return MyModel.fromJson(Data);
}
}
MyFunction调用API选择器
Future<MyModel?> getDataFromApi() async {
try {
var value = await _apiSelector.getApiData(categoryName: "Some Category");
myModel = value as MyModel;
return myModel;
} catch(error) {
print(error);
return error;
}
}
问题出现在getDataFromApi
:中
Future getDataFromApi() async {
await _apiSelector
.getApiData(categoryName: "Some Category")
.then((value) {
myModel = value as MyModel;
print(myModel);
return value;
} ,onError: (error) {
print(error);
return error;
},);
}
正如错误消息所解释的,onError
处理程序无法返回与Future.then
的成功路径返回的类型相同的类型。(请参见https://stackoverflow.com/a/66397222/以获得解释。(这通常是一个编译时错误,但最终是一个运行时错误,因为getDataFromApi
被声明为返回Future
(相当于Future<dynamic>
而不是Future<MyModel>
。
使用带有错误回调的原始Future
API(无论是使用Future.then
的onError
参数还是使用Future.catchError
(直接使用都相当令人困惑。您已经在使用await
,因此没有理由使用Future.then
。使用await
,您可以使用try
-catch
,这使问题更加清晰:
Future<MyModel> getDataFromApi() async {
try {
var myModel = await _apiSelector.getApiData(categoryName: "Some Category");
print(myModel);
return myModel;
} catch (error) {
print(error);
return error; // WRONG: This is not a `MyModel`!
}
}
要解决此问题,catch
块需要返回MyModel
,或者必须抛出异常。
class ApiSelector {
Future getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
//I had to replace throw with Future.value Now All Errors are gone.
return Future.value( 'Error while fetching data');
}
return MyModel.fromJson(Data);
}
}
我希望这也能帮助其他在未来某个时候面临这种错误的人。