refactor: Throw client init exception on client init fail
This changes the behavior when client init fails. It no longer calls logout and does only clear local data while returning all available information in a new exception type so that the SDK consumer can decide to logout or try again to init with these information. This should make it much more rare that users loose their sessions.
This commit is contained in:
parent
872e565de1
commit
a9508d8941
|
|
@ -33,6 +33,7 @@ import 'package:matrix/encryption.dart';
|
|||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/src/models/timeline_chunk.dart';
|
||||
import 'package:matrix/src/utils/cached_stream_controller.dart';
|
||||
import 'package:matrix/src/utils/client_init_exception.dart';
|
||||
import 'package:matrix/src/utils/compute_callback.dart';
|
||||
import 'package:matrix/src/utils/multilock.dart';
|
||||
import 'package:matrix/src/utils/run_benchmarked.dart';
|
||||
|
|
@ -1464,16 +1465,26 @@ class Client extends MatrixApi {
|
|||
newUserID == null ||
|
||||
newDeviceID == null ||
|
||||
newDeviceName == null)) {
|
||||
throw Exception(
|
||||
'If one of [newToken, newUserID, newDeviceID, newDeviceName] is set then all of them must be set!');
|
||||
throw ClientInitPreconditionError(
|
||||
'If one of [newToken, newUserID, newDeviceID, newDeviceName] is set then all of them must be set!',
|
||||
);
|
||||
}
|
||||
|
||||
if (_initLock) throw Exception('[init()] has been called multiple times!');
|
||||
if (_initLock) {
|
||||
throw ClientInitPreconditionError(
|
||||
'[init()] has been called multiple times!',
|
||||
);
|
||||
}
|
||||
_initLock = true;
|
||||
String? olmAccount;
|
||||
String? accessToken;
|
||||
String? userID;
|
||||
try {
|
||||
Logs().i('Initialize client $clientName');
|
||||
if (isLogged()) {
|
||||
throw Exception('User is already logged in! Call [logout()] first!');
|
||||
throw ClientInitPreconditionError(
|
||||
'User is already logged in! Call [logout()] first!',
|
||||
);
|
||||
}
|
||||
|
||||
final databaseBuilder = this.databaseBuilder;
|
||||
|
|
@ -1487,9 +1498,6 @@ class Client extends MatrixApi {
|
|||
_groupCallSessionId = randomAlpha(12);
|
||||
_serverConfigCache.invalidate();
|
||||
|
||||
String? olmAccount;
|
||||
String? accessToken;
|
||||
String? userID;
|
||||
final account = await this.database?.getClient(clientName);
|
||||
if (account != null) {
|
||||
_id = account['client_id'];
|
||||
|
|
@ -1600,12 +1608,24 @@ class Client extends MatrixApi {
|
|||
await firstSyncReceived;
|
||||
}
|
||||
return;
|
||||
} catch (e, s) {
|
||||
Logs().e('Initialization failed', e, s);
|
||||
await logout().catchError((_) => null);
|
||||
onLoginStateChanged.addError(e, s);
|
||||
_initLock = false;
|
||||
} on ClientInitPreconditionError {
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
Logs().wtf('Client initialization failed', e, s);
|
||||
onLoginStateChanged.addError(e, s);
|
||||
final clientInitException = ClientInitException(
|
||||
e,
|
||||
homeserver: homeserver,
|
||||
accessToken: accessToken,
|
||||
userId: userID,
|
||||
deviceId: deviceID,
|
||||
deviceName: deviceName,
|
||||
olmAccount: olmAccount,
|
||||
);
|
||||
await clear();
|
||||
throw clientInitException;
|
||||
} finally {
|
||||
_initLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/// Exception thrown on Client initialization. This object might contain
|
||||
/// enough information to restore the session or to decide if you need to
|
||||
/// logout the session or clear the database.
|
||||
class ClientInitException implements Exception {
|
||||
final Object originalException;
|
||||
final Uri? homeserver;
|
||||
final String? accessToken;
|
||||
final String? userId;
|
||||
final String? deviceId;
|
||||
final String? deviceName;
|
||||
final String? olmAccount;
|
||||
|
||||
ClientInitException(
|
||||
this.originalException, {
|
||||
this.homeserver,
|
||||
this.accessToken,
|
||||
this.userId,
|
||||
this.deviceId,
|
||||
this.deviceName,
|
||||
this.olmAccount,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => originalException.toString();
|
||||
}
|
||||
|
||||
class ClientInitPreconditionError implements Exception {
|
||||
final String cause;
|
||||
|
||||
ClientInitPreconditionError(this.cause);
|
||||
|
||||
@override
|
||||
String toString() => 'Client Init Precondition Error: $cause';
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import 'package:olm/olm.dart' as olm;
|
|||
import 'package:test/test.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/src/utils/client_init_exception.dart';
|
||||
import 'fake_client.dart';
|
||||
import 'fake_database.dart';
|
||||
import 'fake_matrix_api.dart';
|
||||
|
|
@ -1139,6 +1140,41 @@ void main() {
|
|||
reason: '!5345234235:example.com not found as archived room');
|
||||
});
|
||||
|
||||
test('Client Init Exception', () async {
|
||||
try {
|
||||
await olm.init();
|
||||
olm.get_library_version();
|
||||
} catch (e) {
|
||||
olmEnabled = false;
|
||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||
}
|
||||
Logs().w('[LibOlm] Enabled: $olmEnabled');
|
||||
if (!olmEnabled) return;
|
||||
final customClient = Client(
|
||||
'failclient',
|
||||
databaseBuilder: getMatrixSdkDatabase,
|
||||
);
|
||||
try {
|
||||
await customClient.init(
|
||||
newToken: 'testtoken',
|
||||
newDeviceID: 'testdeviceid',
|
||||
newDeviceName: 'testdevicename',
|
||||
newHomeserver: Uri.parse('https://test.server'),
|
||||
newOlmAccount: 'abcd',
|
||||
newUserID: '@user:server',
|
||||
);
|
||||
throw Exception('No exception?');
|
||||
} on ClientInitException catch (error) {
|
||||
expect(error.accessToken, 'testtoken');
|
||||
expect(error.deviceId, 'testdeviceid');
|
||||
expect(error.deviceName, 'testdevicename');
|
||||
expect(error.homeserver, Uri.parse('https://test.server'));
|
||||
expect(error.olmAccount, 'abcd');
|
||||
expect(error.userId, '@user:server');
|
||||
expect(error.toString(), 'Exception: BAD_ACCOUNT_KEY');
|
||||
}
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await matrix.dispose(closeDatabase: true);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue