flutter 用于处理错误Graphql的拦截器

envsm3lx  于 2023-08-07  发布在  Flutter
关注(0)|答案(3)|浏览(187)

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

k3bvogb1

k3bvogb11#

我认为最好使用一个全局错误处理程序小部件,你可以用yout Query小部件调用
下面是我示例错误处理程序

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);
  }
}

字符串
我使用的是小部件,因为我在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,
                      )),
                    ],
                  ));
            })

z18hc3ub

z18hc3ub2#

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

bihw5rsg

bihw5rsg3#

GraphQl本身没有这样的拦截器,他们也不愿意像this thread那样。相反,你可以使用requests_inspector包,它可以与graphql库一起使用:
使用requests_inspector和graphql_flutter库。你只需要用我们的GraphQLInspectorLink Package 你的普通HttpLink,我们就完成了。

final client = GraphQLClient(
    cache: GraphQLCache(),
    link: Link.split(
      (request) => request.isSubscription,
      GraphQLInspectorLink(WebSocketLink('ws://graphqlzero.almansi.me/api')),
      GraphQLInspectorLink(HttpLink('https://graphqlzero.almansi.me/api')),
    ),
  );

字符串
但是这个包似乎不提供回调方法,而是另一种奇怪的方法来通过“摇晃你的手机”获得请求细节,我不确定是否有另一种下降的方法来实现使用这个包或没有,如果没有,你可以fork相同的包来实现你的目标。

相关问题