So I guess this is the error code I am looking for:
ErrorCode = 203 // Bad user authentication
Unfortunately its not easy to test it, because I have to wait 30 days until the token actually expires. Or is there a way I can revoke the token manually (without logging the user out)?
It would be great if I could get an answer to my last question about listening to authentication events with swift. It is very important to handle the logout event, otherwise the app will stop syncing and might even crash. My app is already in production state and I need to deliver an update as soon as possible!
I happened to have a few expired users, and I’ve tried with the code available on our best practices Github repository: you can indeed setup an error handler in Swift like you do for Android, and actually you should, at the very least to be prepared to handle Client Resets. The relevant code snippet looks like:
app.syncManager.errorHandler = { [weak self] error, session in
guard let self = self, let user = session?.parentUser() else { return }
let syncError = error as! SyncError
switch syncError.code {
case .clientResetError:
// Handle client reset
case .clientUserError, .underlyingAuthError:
// Handle logout and other authentication errors
default:
// Other type of errors
print("SyncManager Error: ", error.localizedDescription)
}
}
If the user is not Anonymous, you can try the Revoke all sessions or Disable user in the App User screen.
thanks for your answer. The best practices repository is very helpful.
However, I tried to test my code by revoking all session and/or disabling the user, but that doesn’t trigger the error handler and therefore the app crashes.
What type of users are you logging in with? There’s indeed an issue if you revoke the sessions for an anonymous user, as that is not supposed to happen (anonymous users are temporary, they cease to exist when the token expires), but for regular users that should work.
Thanks for confirming that: do you happen to have a stack trace from Xcode? We have an open ticket for that, having an additional use case would certainly help.
That doesn’t look like a Realm crash, though, more like a piece of the code was waiting to have something to insert into a Dictionary, but the array was empty: have you tried to have breakpoints on Exceptions, and see from where in the code the exception is thrown? Unfortunately the stack is not clear, are you using a Debug build?
I just did and the exception is thrown in the RLMSyncConfiguration.mm
BOOL shouldMakeError = YES;
NSDictionary *custom = nil;
// Note that certain types of errors are 'interactive'; users have several options
// as to how to proceed after the error is reported.
auto errorClass = errorKindForSyncError(error);
switch (errorClass) {
case RLMSyncSystemErrorKindClientReset: {
custom = @{kRLMSyncPathOfRealmBackupCopyKey: recoveryPath,kRLMSyncErrorActionTokenKey: token};
break;
}
case RLMSyncSystemErrorKindPermissionDenied: {
custom = @{kRLMSyncErrorActionTokenKey: token};
break;
}
case RLMSyncSystemErrorKindUser:
case RLMSyncSystemErrorKindSession:
break;
case RLMSyncSystemErrorKindConnection:
case RLMSyncSystemErrorKindClient:
case RLMSyncSystemErrorKindUnknown:
// Report the error. There's nothing the user can do about it, though.
shouldMakeError = error.is_fatal;
break;
}
At this line: custom = @{kRLMSyncErrorActionTokenKey: token};
Error: Thread 2: "*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]"