Query stuck loading forever if different exception is thrown
My query is set up like this:
final qGetTokenRefresh = useQuery<String, GMException>(
'getTokenRefresh', getTokenRefresh, onError: (error) {
print('caught error ');
});
String? tokenRefresh = qGetTokenRefresh.data;
This is the query function:
Future<String> getTokenRefresh() async {
GMJWT? token = await GMJWT.loadToken();
if (token == null) {
throw GMException(errorMessage: 'Could not get token from store!');
}
try {
final response = await GMHttp().post(GMEndpoints.TOKEN_REFRESH, data: {
'refresh': token.refresh,
});
GMJWT newToken = GMJWT.fromJson(json.decode(response.body));
await newToken.persistToken();
if (newToken.access == null) {
throw GMException(errorMessage: 'Access token not given!');
}
return newToken.access!;
} on GMException catch (e) {
if (e.errorCode == 512) {
if (token.access != null) {
return token.access!;
}
}
rethrow;
} catch (e) {
print('different error caught');
rethrow;
}
}
You can see that we have a custom exception type called GMException which the query is expecting, however in some cases, such as the JSON parsing failed, another error gets thrown. This does not trigger the query's "onError" function and is instead caught by "fl_query"
flutter: different error caught
════════ Exception caught by fl_query ══════════════════════════════════════════
The following NoSuchMethodError was thrown retryOperation:
Class 'Response<dynamic>' has no instance getter 'body'.
Receiver: Instance of 'Response<dynamic>'
Tried calling: body
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
object_patch.dart:38
#1 getTokenRefresh (package:gm/modules/auth/controllers/token_refresh.dart:18:58)
token_refresh.dart:18
<asynchronous suspension>
<asynchronous suspension>
#3 Retryer.retryOperation (package:fl_query/src/core/mixins/retryer.dart:17:7)
retryer.dart:17
<asynchronous suspension>
#4 CancelableCompleter.complete.<anonymous closure> (package:async/src/cancelable_operation.dart:425:16)
cancelable_operation.dart:425
<asynchronous suspension>
(elided one frame from dart:async)
════════════════════════════════════════════════════════════════════════════════
The problem is that the query stays in the loading state forever. We noticed this issue in production where users got stuck on the boot screen forever because this query never finished.
Can we have it so that even if the exception type is different, onError gets called and the query is pulled out of loading state?
In addition, each time the app is rebooted the query stays stuck like this, even if the function performs correctly. The only way to get rid of this is clearing the cache, which we can't tell iOS users to do.
Hi, I think that if you know, that your code in getTokenRefresh can throw anything else than GMException, then you should just set the error to dynamic. If we would call onError with the unknown error, the type of that function would have to be dynamic as well, making the Generic essentially useless.
That's a good point. Is it possible to at least remove it from loading state if something other than the expected type is returned or an exception is thrown (even if it's not expected).