颤振中用于处理错误的graphql拦截器

Posted

技术标签:

【中文标题】颤振中用于处理错误的graphql拦截器【英文标题】:interceptor for graphql in flutter for handling error 【发布时间】:2021-04-15 01:39:52 【问题描述】:

我正在使用graphql_flutter 包并希望有一个拦截器, 对于访问令牌,当我的请求以 401 响应代码响应时,我想获取新令牌。

【问题讨论】:

你能发布你的代码吗? 【参考方案1】:

我认为最好使用全局错误处理程序小部件,您可以使用查询小部件调用它

这是我的示例错误处理程序

final _appstate = getIt.get<AppState>();

class ExceptionBuilder extends StatelessWidget 
  final OperationException exception;
  final bool hasData;
  final VoidCallback refetch;
  const ExceptionBuilder(
      Key key,
      @required this.exception,
      @required this.hasData,
      @required this.refetch)
      : super(key: key);

  Widget _resolver(BuildContext context) 
    if ((exception.linkException is LinkException)) 
      return SliverFillRemaining(
        hasScrollBody: false,
        child: Center(
          child: Column(mainAxisSize: MainAxisSize.min, children: [
            emptyList(context, icon: Icons.wifi_off, msg: "Network Error"),
            FlatButton(
                onPressed: refetch,
                child: Text(
                  "retry",
                  style: TextStyle(color: accentColor),
                ))
          ]),
        ),
      );
     else if (exception.graphqlErrors.isNotEmpty) 
      List<String> _errors = exception.graphqlErrors[0].message.split(':');

      if (_errors[1] == " JWTExpired") 
        _appstate.refreshToken();
        return SliverFillRemaining(
            hasScrollBody: false,
            child: Container(
              alignment: Alignment.center,
              child: masker(context, Loader()),
            ));
      
      return SliverFillRemaining(
        hasScrollBody: false,
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          emptyList(context,
              icon: Icons.warning_amber_rounded, msg: "Something went wrong"),
          FlatButton(
              onPressed: refetch,
              child: Text(
                "retry",
                style: TextStyle(color: accentColor),
              ))
        ]),
      );
    

    return SliverToBoxAdapter(
      child: SizedBox.shrink(),
    );
  

  @override
  Widget build(BuildContext context) 
    return _resolver(context);
  

我正在使用 sliver 小部件,因为我在 CustomScrollView 中调用它

这里是解析器方法

  List<Widget> _resolver(BuildContext context, QueryResult result,
      FetchMore fetchMore, Refetch refetch) 
    if (result.isLoading && isNull(result.data)) 
      return [
        SliverFillRemaining(
            hasScrollBody: false,
            child: Container(
              alignment: Alignment.center,
              child: masker(context, Loader()),
            ))
      ];
    

    if (!isNull(result.data)) 
      List<PersonMiniSchedule> _schedule = scheduleMiniJsonToList(
        result.data['person_max_score_per_schedule'],
      );

      return [
        SliverToBoxAdapter(child: SizedBox(height: 30)),
        _schedule.isEmpty
            ? SliverFillRemaining(
                child: Center(
                    child: emptyList(context,
                        icon: FontAwesomeIcons.book, msg: "No Schedules Yet.")),
              )
            : SliverList(
                delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) 
                return ScheduleCard(
                  schedule: _schedule[index],
                );
              , childCount: _schedule.length)),
      ];
    

    if (result.hasException) 
      return [
        ExceptionBuilder(
            exception: result.exception,
            hasData: isNull(result.data),
            refetch: refetch)
      ];
    

    return [
      SliverToBoxAdapter(
        child: SizedBox.shrink(),
      )
    ];
  

这里是查询小部件

Query(
            options: QueryOptions(
                variables: 'id': _appstate.token.hasuraId,
                document: yourQuery()),
            builder: (QueryResult result,
                VoidCallback refetch, FetchMore fetchMore) 
              return RefreshIndicator(
                  onRefresh: () async => refetch(),
                  child: CustomScrollView(
                    slivers: [
                      ..._resolver(context, result, fetchMore, refetch),
                      SliverToBoxAdapter(
                          child: SizedBox(
                        height: 200,
                      )),
                    ],
                  ));
            )

【讨论】:

【参考方案2】:

在 (builder:) 中,您可以使用 if (result.hasException) ,当您从 graphql 收到错误时,它将自动触发。因此,请检查错误是否为 JWT 过期。您可以通过 result.exception.toString() 进行检查。然后您可以运行其他突变以刷新令牌,然后重新初始化客户端。

【讨论】:

以上是关于颤振中用于处理错误的graphql拦截器的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振发布方法中修复“未处理的异常:用于空值的空检查运算符”

如何使用 dartz 在颤振中重构功能错误处理

如何在 GraphQL 中处理错误并发送响应

Apollo GraphQL 本地和全局错误处理

GraphQL,中继:处理错误

Apollo GraphQL 错误处理