Merge pull request #1670 from famedly/krille/throw-client-init-exception

refactor: Throw client init exception on client init fail
This commit is contained in:
Krille-chan 2024-01-05 09:58:10 +01:00 committed by GitHub
commit 025d8c043b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 12 deletions

View File

@ -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;
}
}

View File

@ -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';
}

View File

@ -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);
});