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