Skip to content

Commit

Permalink
Add MigrationRequiredException (#1459)
Browse files Browse the repository at this point in the history
* Add MigrationRequiredException

* Re-include the error code in the error message
  • Loading branch information
nirinchev authored Jan 8, 2024
1 parent 9b947ff commit ecdce26
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
```

The map keys may not contain `.` or start with `$`. (Issue [#685](https://github.com/realm/realm-dart/issues/685))
* Added a new exception - `MigrationRequiredException` that will be thrown when a local Realm is opened with a schema that differs from the schema on disk and no migration callback is supplied. Additionally, a `helpLink` property has been added to `RealmException` and its subclasses to provide a link to the documentation for the error. (Issue [#1448](https://github.com/realm/realm-dart/issues/1448))

### Fixed
* Fixed warnings being emitted by the realm generator requesting that `xyz.g.dart` be included with `part 'xyz.g.dart';` for `xyz.dart` files that import `realm` but don't have realm models defined. Those should not need generated parts and including the part file would have resulted in an empty file with `// ignore_for_file: type=lint` being generated. (PR [#1443](https://github.com/realm/realm-dart/pull/1443))
Expand Down
15 changes: 10 additions & 5 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,13 @@ class _RealmCore {
throw UserCallbackException(lastError!.userError!);
}

throw RealmException('${errorMessage != null ? "$errorMessage. " : ""}${lastError ?? ""}');
final message = '${errorMessage != null ? "$errorMessage. " : ""}${lastError ?? ""}';
switch (lastError?.code) {
case realm_errno.RLM_ERR_SCHEMA_MISMATCH:
throw MigrationRequiredException(message);
default:
throw RealmException(message);
}
});
}

Expand Down Expand Up @@ -694,7 +700,8 @@ class _RealmCore {
if (error != nullptr) {
final err = arena<realm_error>();
bool success = _realmLib.realm_get_async_error(error, err);
completer.completeError(RealmException("Failed to open realm ${success ? err.ref.toLastError().toString() : ''}"));
final lastError = success ? err.ref.toLastError() : null;
completer.completeError(RealmException("Failed to open realm${lastError?.message ?? ''}"));
return;
}

Expand Down Expand Up @@ -2888,9 +2895,7 @@ class LastError {
LastError(this.code, [this.message, this.userError]);

@override
String toString() {
return "Error code: $code ${(message != null ? ". Message: $message" : "")}";
}
String toString() => "${message ?? 'No message'}. Error code: $code.";
}

// Flag to enable trace on finalization.
Expand Down
18 changes: 17 additions & 1 deletion lib/src/realm_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -582,14 +582,30 @@ extension RealmObjectInternal on RealmObjectBase {
class RealmException implements Exception {
final String message;

RealmException(this.message);
/// A link to the documentation that explains how to resolve the error.
final String? helpLink;

RealmException(this.message, {this.helpLink});

@override
String toString() {
return "RealmException: $message";
}
}

/// An exception thrown when a Realm is opened with a different schema and a migration is required.
/// See [LocalConfiguration.migrationCallback] for more details.
class MigrationRequiredException extends RealmException {
MigrationRequiredException(String message)
: super(message,
helpLink: "https://www.mongodb.com/docs/realm/sdk/flutter/realm-database/model-data/update-realm-object-schema/#manually-migrate-schema");

@override
String toString() {
return "Migration required: $message. See $helpLink for more details.";
}
}

/// An exception throws during execution of a user callback - e.g. during migration or initial data population.
/// {@category Realm}
class UserCallbackException extends RealmException {
Expand Down
4 changes: 1 addition & 3 deletions test/app_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:test/expect.dart' hide throws;
import 'package:path/path.dart' as path;
import 'package:crypto/crypto.dart';
Expand Down Expand Up @@ -294,7 +292,7 @@ Future<void> main([List<String>? args]) async {
expect(app.currentUser, user2);
expect(
() => app.switchUser(user1),
throws<RealmException>("Switch user failed. Error code: 4101 . Message: User is no longer valid or is logged out"),
throws<RealmException>("Switch user failed. User is no longer valid or is logged out"),
);
});

Expand Down
6 changes: 5 additions & 1 deletion test/migration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ Future<void> main([List<String>? args]) async {
invoked = true;
});

expect(() => getRealm(config2), throws<RealmException>('Migration is required due to the following errors'));
expect(
() => getRealm(config2),
throwsA(isA<MigrationRequiredException>()
.having((e) => e.message, 'message', contains('Migration is required due to the following errors'))
.having((e) => e.helpLink, 'helpLink', isNotNull)));
expect(invoked, false);
});

Expand Down

0 comments on commit ecdce26

Please sign in to comment.