Skip to content

Commit

Permalink
fix: Make API-Service more robust to network outages (#645)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomBursch authored Feb 9, 2025
1 parent 13b66c3 commit 4c6d2b7
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions kitchenowl/lib/services/api/api_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:kitchenowl/helpers/named_bytearray.dart';
import 'package:kitchenowl/models/household.dart';
import 'package:kitchenowl/models/token.dart';
import 'package:socket_io_client/socket_io_client.dart';
import 'package:tuple/tuple.dart';

// Export extensions
export 'user.dart';
Expand Down Expand Up @@ -173,19 +172,21 @@ class ApiService {
Connection status = Connection.disconnected;
if (baseUrl.isNotEmpty) {
final healthy = await getInstance().healthy();
_serverInfoNotifier.value = healthy.item2;
if (healthy.item1) {
if (healthy.item2 != null &&
healthy.item2!['min_frontend_version'] <=
_serverInfoNotifier.value = healthy.body;
if (healthy.success) {
if (healthy.body != null &&
healthy.body!['min_frontend_version'] <=
(int.tryParse((await Config.packageInfo)?.buildNumber ?? '0') ??
0) &&
(healthy.item2!['version'] ?? 0) >= Config.MIN_BACKEND_VERSION) {
await getInstance().refreshAuth()
? status = Connection.authenticated
: status = Connection.connected;
(healthy.body!['version'] ?? 0) >= Config.MIN_BACKEND_VERSION) {
status = switch (await getInstance().refreshAuth()) {
null => Connection.disconnected,
true => Connection.authenticated,
false => Connection.connected,
};
} else {
status = healthy.item2 == null ||
(healthy.item2!['version'] ?? 0) < Config.MIN_BACKEND_VERSION
status = healthy.body == null ||
(healthy.body!['version'] ?? 0) < Config.MIN_BACKEND_VERSION
? Connection.unsupportedBackend
: Connection.unsupportedFrontend;
}
Expand Down Expand Up @@ -309,17 +310,17 @@ class ApiService {
_connectionNotifier.value = newState;
}

Future<Tuple2<bool, Map<String, dynamic>?>> healthy() async {
Future<({bool success, Map<String, dynamic>? body})> healthy() async {
try {
final res = await get(
'/health/8M4F88S8ooi4sMbLBfkkV7ctWwgibW6V',
refreshOnException: false,
timeout: _TIMEOUT_HEALTH,
);
if (res.statusCode == 200) {
return Tuple2(
jsonDecode(res.body)['msg'] == 'OK',
jsonDecode(res.body),
return (
success: jsonDecode(res.body)['msg'] == 'OK',
body: jsonDecode(res.body) as Map<String, dynamic>?,
);
} else {
debugPrint("Health check: Response code ${res.statusCode}");
Expand All @@ -328,10 +329,10 @@ class ApiService {
debugPrint("Health check: ${ex.toString()}");
}

return const Tuple2(false, null);
return const (success: false, body: null);
}

Future<bool> refreshAuth() async {
Future<bool?> refreshAuth() async {
if (_handleTokenBeforeReauth != null) {
_refreshToken = await _handleTokenBeforeReauth!(_refreshToken);
}
Expand All @@ -353,13 +354,13 @@ class ApiService {
if (_handleTokenRotation != null) {
_handleTokenRotation!(_refreshToken!);
}
_setConnectionState(Connection.authenticated);

return true;
} else if (res.statusCode == 401 || res.statusCode == 403) {
return false;
}
} catch (_) {}

return false;
return null;
}

Future<String?> login(String username, String password) async {
Expand Down

0 comments on commit 4c6d2b7

Please sign in to comment.