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/matrix.dart';
import 'package:matrix/src/models/timeline_chunk.dart'; import 'package:matrix/src/models/timeline_chunk.dart';
import 'package:matrix/src/utils/cached_stream_controller.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/compute_callback.dart';
import 'package:matrix/src/utils/multilock.dart'; import 'package:matrix/src/utils/multilock.dart';
import 'package:matrix/src/utils/run_benchmarked.dart'; import 'package:matrix/src/utils/run_benchmarked.dart';
@ -1464,16 +1465,26 @@ class Client extends MatrixApi {
newUserID == null || newUserID == null ||
newDeviceID == null || newDeviceID == null ||
newDeviceName == null)) { newDeviceName == null)) {
throw Exception( throw ClientInitPreconditionError(
'If one of [newToken, newUserID, newDeviceID, newDeviceName] is set then all of them must be set!'); '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; _initLock = true;
String? olmAccount;
String? accessToken;
String? userID;
try { try {
Logs().i('Initialize client $clientName'); Logs().i('Initialize client $clientName');
if (isLogged()) { 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; final databaseBuilder = this.databaseBuilder;
@ -1487,9 +1498,6 @@ class Client extends MatrixApi {
_groupCallSessionId = randomAlpha(12); _groupCallSessionId = randomAlpha(12);
_serverConfigCache.invalidate(); _serverConfigCache.invalidate();
String? olmAccount;
String? accessToken;
String? userID;
final account = await this.database?.getClient(clientName); final account = await this.database?.getClient(clientName);
if (account != null) { if (account != null) {
_id = account['client_id']; _id = account['client_id'];
@ -1600,12 +1608,24 @@ class Client extends MatrixApi {
await firstSyncReceived; await firstSyncReceived;
} }
return; return;
} catch (e, s) { } on ClientInitPreconditionError {
Logs().e('Initialization failed', e, s);
await logout().catchError((_) => null);
onLoginStateChanged.addError(e, s);
_initLock = false;
rethrow; 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:test/test.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:matrix/src/utils/client_init_exception.dart';
import 'fake_client.dart'; import 'fake_client.dart';
import 'fake_database.dart'; import 'fake_database.dart';
import 'fake_matrix_api.dart'; import 'fake_matrix_api.dart';
@ -1139,6 +1140,41 @@ void main() {
reason: '!5345234235:example.com not found as archived room'); 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 { tearDown(() async {
await matrix.dispose(closeDatabase: true); await matrix.dispose(closeDatabase: true);
}); });