簡體   English   中英

flutter 中 graphql 的攔截器,用於處理錯誤

[英]interceptor for graphql in flutter for handling error

我正在使用graphql_flutter package 並希望為此設置一個攔截器,對於訪問令牌,我想在我的請求以 401 響應代碼響應時獲取新令牌。

我認為最好使用全局錯誤處理程序小部件,您可以使用 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);
  }
}

我正在使用 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,
                      )),
                    ],
                  ));
            })

在 (builder:{}) 中,您可以使用 if (result.hasException) {},當您從 graphql 收到錯誤時,它將自動觸發。 因此,請檢查錯誤是否為 JWT 過期。 您可以通過 result.exception.toString() 進行檢查。 然后您可以運行其他突變以刷新令牌,然后重新初始化客戶端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM