Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
610 views
in Technique[技术] by (71.8m points)

dart - interceptor for graphql in flutter for handling error

I'm using graphql_flutter package and want to have a interceptor for that, for access token i want to get new token when my request responded with 401 response code.

question from:https://stackoverflow.com/questions/65644389/interceptor-for-graphql-in-flutter-for-handling-error

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

i think its better to use a global error handler widget that you can call with yout Query widget

here is my example error handler

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

I am using sliver widget because i am calling it in CustomScrollView

here is the resolver method

  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(),
      )
    ];
  }

here is the Query widget

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...