Skip to content

Commit

Permalink
Avoid SyncErrorCode dep on realm_binding.dart
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsenko committed May 31, 2024
1 parent 7cc3038 commit ee55189
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 40 deletions.
10 changes: 4 additions & 6 deletions packages/realm_dart/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -718,25 +718,23 @@ final class CompensatingWriteError extends SyncError {
extension SyncErrorInternal on SyncError {
static SyncError createSyncError(SyncErrorDetails error, {App? app}) {
//Client reset can be requested with isClientResetRequested disregarding the ErrorCode
SyncErrorCode errorCode = SyncErrorCode.fromInt(error.code);
return switch (errorCode) {
return switch (error.code) {
SyncErrorCode.autoClientResetFailed => ClientResetError._(
error.message,
errorCode,
error.code,
app,
error.userError,
originalFilePath: error.originalFilePath,
backupFilePath: error.backupFilePath,
),
SyncErrorCode.clientReset =>
ClientResetError._(error.message, errorCode, app, error.userError, originalFilePath: error.originalFilePath, backupFilePath: error.backupFilePath),
ClientResetError._(error.message, error.code, app, error.userError, originalFilePath: error.originalFilePath, backupFilePath: error.backupFilePath),
SyncErrorCode.compensatingWrite => CompensatingWriteError._(
error.message,
error.userError,
compensatingWrites: error.compensatingWrites,
),
_ => SyncError._(error.message, errorCode, error.userError),
_ => SyncError._(error.message, error.code, error.userError),
};
}
}
3 changes: 2 additions & 1 deletion packages/realm_dart/lib/src/handles/app_handle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import '../../realm.dart';

import 'credentials_handle.dart';
import 'native/app_handle.dart' if (dart.library.js_interop) 'web/app_handle.dart' as impl;
import 'user_handle.dart';

import 'native/app_handle.dart' if (dart.library.js_interop) 'web/app_handle.dart' as impl;

abstract interface class AppHandle {
factory AppHandle.from(AppConfiguration configuration) = impl.AppHandle.from;
static AppHandle? get(String id, String? baseUrl) => impl.AppHandle.get(id, baseUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class AsyncOpenTaskHandle extends HandleBase<realm_async_open_task_t> implements
return AsyncOpenTaskHandle(asyncOpenTaskPtr);
}

@override
Future<RealmHandle> openAsync(CancellationToken? cancellationToken) {
final completer = CancellableCompleter<RealmHandle>(cancellationToken);
if (!completer.isCancelled) {
Expand All @@ -40,10 +41,12 @@ class AsyncOpenTaskHandle extends HandleBase<realm_async_open_task_t> implements
return completer.future;
}

@override
void cancel() {
realmLib.realm_async_open_task_cancel(pointer);
}

@override
AsyncOpenTaskProgressNotificationTokenHandle registerProgressNotifier(
RealmAsyncOpenProgressNotificationsController controller,
) {
Expand Down
45 changes: 42 additions & 3 deletions packages/realm_dart/lib/src/handles/native/from_native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ extension RealmSyncErrorEx on realm_sync_error {

return SyncErrorDetails(
message,
status.error,
status.error.toSyncErrorCode(),
user_code_error.toUserCodeError(),
isFatal: is_fatal,
isClientResetRequested: is_client_reset_requested,
Expand Down Expand Up @@ -198,11 +198,50 @@ extension PointerRealmSyncErrorCompensatingWriteInfoEx on Pointer<realm_sync_err
extension PointerRealmErrorEx on Pointer<realm_error_t> {
SyncError toDart() {
final message = ref.message.cast<Utf8>().toDartString();
final details = SyncErrorDetails(message, ref.error, ref.user_code_error.toUserCodeError());
final details = SyncErrorDetails(message, ref.error.toSyncErrorCode(), ref.user_code_error.toUserCodeError());
return SyncErrorInternal.createSyncError(details);
}
}

extension IntEx on int {
SyncErrorCode toSyncErrorCode() => switch (this) {
realm_errno.RLM_ERR_RUNTIME => SyncErrorCode.runtimeError,
realm_errno.RLM_ERR_BAD_CHANGESET => SyncErrorCode.badChangeset,
realm_errno.RLM_ERR_BAD_SYNC_PARTITION_VALUE => SyncErrorCode.badPartitionValue,
realm_errno.RLM_ERR_SYNC_PROTOCOL_INVARIANT_FAILED => SyncErrorCode.protocolInvariantFailed,
realm_errno.RLM_ERR_INVALID_SUBSCRIPTION_QUERY => SyncErrorCode.invalidSubscriptionQuery,
realm_errno.RLM_ERR_SYNC_CLIENT_RESET_REQUIRED => SyncErrorCode.clientReset,
realm_errno.RLM_ERR_SYNC_INVALID_SCHEMA_CHANGE => SyncErrorCode.invalidSchemaChange,
realm_errno.RLM_ERR_SYNC_PERMISSION_DENIED => SyncErrorCode.permissionDenied,
realm_errno.RLM_ERR_SYNC_SERVER_PERMISSIONS_CHANGED => SyncErrorCode.serverPermissionsChanged,
realm_errno.RLM_ERR_SYNC_USER_MISMATCH => SyncErrorCode.userMismatch,
realm_errno.RLM_ERR_SYNC_WRITE_NOT_ALLOWED => SyncErrorCode.writeNotAllowed,
realm_errno.RLM_ERR_AUTO_CLIENT_RESET_FAILED => SyncErrorCode.autoClientResetFailed,
realm_errno.RLM_ERR_WRONG_SYNC_TYPE => SyncErrorCode.wrongSyncType,
realm_errno.RLM_ERR_SYNC_COMPENSATING_WRITE => SyncErrorCode.compensatingWrite,
_ => throw RealmError("Unknown sync error code $this"),
};
}

extension SyncErrorCodeEx on SyncErrorCode {
int get code => switch (this) {
SyncErrorCode.runtimeError => realm_errno.RLM_ERR_RUNTIME,
SyncErrorCode.badChangeset => realm_errno.RLM_ERR_BAD_CHANGESET,
SyncErrorCode.badPartitionValue => realm_errno.RLM_ERR_BAD_SYNC_PARTITION_VALUE,
SyncErrorCode.protocolInvariantFailed => realm_errno.RLM_ERR_SYNC_PROTOCOL_INVARIANT_FAILED,
SyncErrorCode.invalidSubscriptionQuery => realm_errno.RLM_ERR_INVALID_SUBSCRIPTION_QUERY,
SyncErrorCode.clientReset => realm_errno.RLM_ERR_SYNC_CLIENT_RESET_REQUIRED,
SyncErrorCode.invalidSchemaChange => realm_errno.RLM_ERR_SYNC_INVALID_SCHEMA_CHANGE,
SyncErrorCode.permissionDenied => realm_errno.RLM_ERR_SYNC_PERMISSION_DENIED,
SyncErrorCode.serverPermissionsChanged => realm_errno.RLM_ERR_SYNC_SERVER_PERMISSIONS_CHANGED,
SyncErrorCode.userMismatch => realm_errno.RLM_ERR_SYNC_USER_MISMATCH,
SyncErrorCode.writeNotAllowed => realm_errno.RLM_ERR_SYNC_WRITE_NOT_ALLOWED,
SyncErrorCode.autoClientResetFailed => realm_errno.RLM_ERR_AUTO_CLIENT_RESET_FAILED,
SyncErrorCode.wrongSyncType => realm_errno.RLM_ERR_WRONG_SYNC_TYPE,
SyncErrorCode.compensatingWrite => realm_errno.RLM_ERR_SYNC_COMPENSATING_WRITE,
};
}

extension ObjectEx on Object {
Pointer<Void> toPersistentHandle() {
return realmLib.realm_dart_object_to_persistent_handle(this);
Expand Down Expand Up @@ -317,7 +356,7 @@ extension PlatformEx on Platform {
/// @nodoc
class SyncErrorDetails {
final String message;
final int code;
final SyncErrorCode code;
final String? path;
final bool isFatal;
final bool isClientResetRequested;
Expand Down
3 changes: 3 additions & 0 deletions packages/realm_dart/lib/src/handles/native/realm_handle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,17 @@ class RealmHandle extends HandleBase<shared_realm> implements intf.RealmHandle {
}
}

@override
bool get isWritable {
return realmLib.realm_is_writable(pointer);
}

@override
void rollbackWrite() {
realmLib.realm_rollback(pointer).raiseLastErrorIfFalse();
}

@override
bool refresh() {
return using((arena) {
final didRefresh = arena<Bool>();
Expand Down
3 changes: 2 additions & 1 deletion packages/realm_dart/lib/src/handles/native/user_handle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'dart:ffi';
import '../../credentials.dart';
import '../../realm_dart.dart';
import '../../user.dart';
import '../user_handle.dart' as intf;
import 'app_handle.dart';
import 'convert.dart';
import 'convert_native.dart';
Expand All @@ -20,6 +19,8 @@ import 'realm_bindings.dart';
import 'realm_library.dart';
import 'scheduler_handle.dart';

import '../user_handle.dart' as intf;

class UserHandle extends HandleBase<realm_user> implements intf.UserHandle {
UserHandle(Pointer<realm_user> pointer) : super(pointer, 24);

Expand Down
5 changes: 0 additions & 5 deletions packages/realm_dart/lib/src/handles/realm_bindings.dart

This file was deleted.

38 changes: 14 additions & 24 deletions packages/realm_dart/lib/src/session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import 'dart:async';

import '../realm.dart';
import 'handles/realm_bindings.dart';
import 'handles/session_handle.dart';
import 'user.dart';

Expand Down Expand Up @@ -232,65 +231,56 @@ enum ProgressMode {
/// Error code enumeration, indicating the type of [SyncError].
enum SyncErrorCode {
/// Unrecognized error code. It usually indicates incompatibility between the App Services server and client SDK versions.
runtimeError(realm_errno.RLM_ERR_RUNTIME),
runtimeError,

/// The partition value specified by the user is not valid - i.e. its the wrong type or is encoded incorrectly.
badPartitionValue(realm_errno.RLM_ERR_BAD_SYNC_PARTITION_VALUE),
badPartitionValue,

/// A fundamental invariant in the communication between the client and the server was not upheld. This typically indicates
/// a bug in the synchronization layer and should be reported at https://github.com/realm/realm-core/issues.
protocolInvariantFailed(realm_errno.RLM_ERR_SYNC_PROTOCOL_INVARIANT_FAILED),
protocolInvariantFailed,

/// The changeset is invalid.
badChangeset(realm_errno.RLM_ERR_BAD_CHANGESET),
badChangeset,

/// The client attempted to create a subscription for a query is invalid/malformed.
invalidSubscriptionQuery(realm_errno.RLM_ERR_INVALID_SUBSCRIPTION_QUERY),
invalidSubscriptionQuery,

/// A client reset has occurred. This error code will only be reported via a [ClientResetError] and only
/// in the case manual client reset handling is required - either via [ManualRecoveryHandler] or when
/// `onManualReset` is invoked on one of the automatic client reset handlers.
clientReset(realm_errno.RLM_ERR_SYNC_CLIENT_RESET_REQUIRED),
clientReset,

/// The client attempted to upload an invalid schema change - either an additive schema change
/// when developer mode is <c>off</c> or a destructive schema change.
invalidSchemaChange(realm_errno.RLM_ERR_SYNC_INVALID_SCHEMA_CHANGE),
invalidSchemaChange,

/// Permission to Realm has been denied.
permissionDenied(realm_errno.RLM_ERR_SYNC_PERMISSION_DENIED),
permissionDenied,

/// The server permissions for this file have changed since the last time it was used.
serverPermissionsChanged(realm_errno.RLM_ERR_SYNC_SERVER_PERMISSIONS_CHANGED),
serverPermissionsChanged,

/// The user for this session doesn't match the user who originally created the file. This can happen
/// if you explicitly specify the Realm file path in the configuration and you open the Realm first with
/// user A, then with user B without changing the on-disk path.
userMismatch(realm_errno.RLM_ERR_SYNC_USER_MISMATCH),
userMismatch,

/// Client attempted a write that is disallowed by permissions, or modifies an object
/// outside the current query - this will result in a [CompensatingWriteError].
writeNotAllowed(realm_errno.RLM_ERR_SYNC_WRITE_NOT_ALLOWED),
writeNotAllowed,

/// Automatic client reset has failed. This will only be reported via [ClientResetError]
/// when an automatic client reset handler was used but it failed to perform the client reset operation -
/// typically due to a breaking schema change in the server schema or due to an exception occurring in the
/// before or after client reset callbacks.
autoClientResetFailed(realm_errno.RLM_ERR_AUTO_CLIENT_RESET_FAILED),
autoClientResetFailed,

/// The wrong sync type was used to connect to the server. This means that you're trying to connect
/// to an app configured to use partition sync.
wrongSyncType(realm_errno.RLM_ERR_WRONG_SYNC_TYPE),
wrongSyncType,

/// Client attempted a write that is disallowed by permissions, or modifies an
/// object outside the current query, and the server undid the modification.
compensatingWrite(realm_errno.RLM_ERR_SYNC_COMPENSATING_WRITE);

static final Map<int, SyncErrorCode> _valuesMap = {for (var value in SyncErrorCode.values) value.code: value};

static SyncErrorCode fromInt(int code) {
return SyncErrorCode._valuesMap[code] ?? SyncErrorCode.runtimeError;
}

final int code;
const SyncErrorCode(this.code);
compensatingWrite;
}

0 comments on commit ee55189

Please sign in to comment.