Skip to content
This repository has been archived by the owner on May 13, 2023. It is now read-only.

fix: Retry access token refresh when offline #71

Merged
merged 8 commits into from Apr 30, 2022
8 changes: 8 additions & 0 deletions lib/src/fetch.dart
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io';

import 'package:gotrue/src/fetch_options.dart';
import 'package:gotrue/src/gotrue_error.dart';
Expand All @@ -25,6 +26,11 @@ class Fetch {
} on FormatException catch (_) {
return GotrueError(error.body);
}
} else if (error is SocketException) {
return GotrueError(
error.toString(),
statusCode: error.runtimeType.toString(),
);
} else {
return GotrueError(error.toString());
}
Expand Down Expand Up @@ -74,6 +80,8 @@ class Fetch {
} else {
throw response;
}
} on SocketException catch (e) {
return GotrueResponse(error: handleError(e));
} catch (e) {
return GotrueResponse(error: handleError(e));
} finally {
Expand Down
8 changes: 4 additions & 4 deletions lib/src/gotrue_api.dart
Expand Up @@ -37,14 +37,14 @@ class GoTrueApi {
body,
options: fetchOptions,
);
final data = response.rawData as Map<String, dynamic>;
final data = response.rawData as Map<String, dynamic>?;
if (response.error != null) {
return GotrueSessionResponse(error: response.error);
} else if (data['access_token'] == null) {
} else if (data?['access_token'] == null) {
// email validation required
User? user;
if (data['id'] != null) {
user = User.fromJson(data);
if (data?['id'] != null) {
user = User.fromJson(data!);
}
return GotrueSessionResponse(user: user);
} else {
Expand Down
17 changes: 13 additions & 4 deletions lib/src/gotrue_client.dart
Expand Up @@ -434,15 +434,19 @@ class GoTrueClient {
final nextDuration = expiresIn - refreshDurationBeforeExpires;
if (nextDuration > 0) {
final timerDuration = Duration(seconds: nextDuration);
_refreshTokenTimer = Timer(timerDuration, () {
_callRefreshToken();
});
_setTokenRefreshTimer(timerDuration);
} else {
_callRefreshToken();
}
}
}

void _setTokenRefreshTimer(Duration timerDuration) {
_refreshTokenTimer = Timer(timerDuration, () {
_callRefreshToken();
});
}

void _removeSession() {
currentSession = null;
currentUser = null;
Expand All @@ -464,7 +468,12 @@ class GoTrueClient {
}

final response = await api.refreshAccessToken(token, jwt);
if (response.error != null) return response;
if (response.error != null) {
if (response.error!.statusCode == 'SocketException') {
_setTokenRefreshTimer(const Duration(seconds: 5));
dshukertjr marked this conversation as resolved.
Show resolved Hide resolved
}
return response;
}
if (response.data == null) {
final error = GotrueError('Invalid session data.');
return GotrueSessionResponse(error: error);
Expand Down
8 changes: 6 additions & 2 deletions lib/src/gotrue_error.dart
@@ -1,10 +1,14 @@
class GotrueError {
String message;
String? statusCode;

GotrueError(this.message);
GotrueError(
this.message, {
this.statusCode,
});

@override
String toString() {
return 'GotrueError(message: $message)';
return 'GotrueError(message: $message, statusCode: $statusCode)';
}
}