You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用Riverpod+Dartz时FutureProvider与Future<Either>类型不匹配问题问询

报错原因

你定义的activeCourseProvider泛型指定返回值类型为List<CourseModel>,但调用的activeCourses方法实际返回类型是Future<Either<ApiFailures, List<CourseModel>>>,二者类型不匹配触发编译错误。

原报错中文翻译:返回类型 Future<Either<ApiFailures, List<CourseModel>>> 不符合闭包上下文要求的 Future<List<CourseModel>> 类型。

解决方案

根据你需要的错误处理方式,可选以下两种方案:

方案1:保留Dartz Either的函数式错误处理(推荐)

直接修改Provider的泛型声明,让Provider直接返回Either类型,你可以在UI层自主处理成功/失败分支,完整保留自定义ApiFailures的错误处理能力。
修改后的Provider代码如下:

final activeCourseProvider = FutureProvider.autoDispose.family<Either<ApiFailures, List<CourseModel>>, int>((ref, yearId) {
  final _courseRepository = ref.watch(coursesRepositoryProvider);
  return _courseRepository.activeCourses(yearId);
});

UI层调用示例:

ref.watch(activeCourseProvider(传入的yearId)).when(
  loading: () => const CircularProgressIndicator(),
  error: (error, stackTrace) => Text('请求异常:$error'),
  data: (eitherData) => eitherData.fold(
    (failure) => Text(failure.map(
      noConnection: (_) => "当前无网络连接,请检查网络后重试",
      notFound: (_) => "未查询到对应课程信息",
    ).toString()),
    (courseList) => ListView.builder(
      itemCount: courseList.length,
      itemBuilder: (context, index) => CourseItem(data: courseList[index]),
    ),
  ),
);

方案2:适配Riverpod原生错误处理逻辑

如果你不需要在UI层操作Either,也可以在Provider内部处理Either分支,将失败分支的ApiFailures作为异常抛出,直接复用Riverpod的AsyncError能力处理错误。
修改后的Provider代码如下:

final activeCourseProvider = FutureProvider.autoDispose.family<List<CourseModel>, int>((ref, yearId) async {
  final _courseRepository = ref.watch(coursesRepositoryProvider);
  final resultEither = await _courseRepository.activeCourses(yearId);
  return resultEither.fold(
    (failure) => throw failure,
    (courses) => courses,
  );
});

UI层可以直接在when的error回调中拿到抛出的ApiFailures对象,做对应的错误提示即可。


内容的提问来源于stack exchange,提问作者Fahmi Sawalha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:57:05