Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected Exception #2400

Closed
ivanrlg opened this issue May 26, 2021 · 9 comments · Fixed by #2438
Closed

Unexpected Exception #2400

ivanrlg opened this issue May 26, 2021 · 9 comments · Fixed by #2438
Assignees

Comments

@ivanrlg
Copy link

ivanrlg commented May 26, 2021

Goals

Discover the cause of the exception

Expected Results

Not have the unexpected exception

Actual Results

Entrando GetTokenAsync: 5/25/2021 7:42:59 PM
The thread 0x3808 has exited with code 0 (0x0).
'FusionMedicalRealm.UWP.exe' (Win32): Loaded 'C:\Windows\System32\Windows.Shell.ServiceHostBuilder.dll'.
The thread 0x41f0 has exited with code 0 (0x0).
Exception thrown at 0x00007FFCAB8F4B89 (KernelBase.dll) in FusionMedicalRealm.UWP.exe: 0x000006D9: There are no more endpoints available from the endpoint mapper.
onecoreuap\base\appmodel\statemanager\roamingrpc\stateroamingrpcclient.cpp(124)\Windows.Storage.ApplicationData.dll!00007FFC801A3CB8: (caller: 00007FFC801A4586) ReturnHr(5) tid(1268) 800706D9 There are no more endpoints available from the endpoint mapper.
    Msg:[c_SignalRoamingDataChange 2]
Entrando CheckSessions: 5/25/2021 7:43:01 PM
Entrando SetUserFromObjet: 5/25/2021 7:43:01 PM
      In GetInstanceAsync  Time: 5/25/2021 7:43:03 PM
Progress Realm: 345 Mb /345 Mb
Exception thrown at 0x00007FFCAB8F4B89 in FusionMedicalRealm.UWP.exe: Microsoft C++ exception: EEMessageException at memory location 0x0000008FEFC7E2C0.
The thread 0x3ee8 has exited with code 0 (0x0).
      In GetInstanceAsync  Time: 5/25/2021 7:43:05 PM
Progress Realm: 345 Mb /345 Mb
Exception thrown at 0x00007FFCAB8F4B89 in FusionMedicalRealm.UWP.exe: Microsoft C++ exception: EEMessageException at memory location 0x0000008FEFC7E2C0.
      In GetInstanceAsync  Time: 5/25/2021 7:43:05 PM
Progress Realm: 345 Mb /345 Mb
Exception thrown at 0x00007FFCAB8F4B89 in FusionMedicalRealm.UWP.exe: Microsoft C++ exception: EEMessageException at memory location 0x0000008FEFC7E2C0.
An unhandled exception of type 'System.NullReferenceException' occurred in Realm.dll
Object reference not set to an instance of an object.

Steps to Reproduce

When installing on a new device after syncing the first time, the exception occurs when I try to search for a record.

I have tried to catch him with a try but it is not possible.

It is important to note that after the exception occurs, the second time I try to enter the app it no longer happens.

Code Sample

 try
            {
                SessionsModel SessionByIdApp = (await SessionsServices.ReadByPredicate(p => p.IdApp == IdApp && p.Email == Email)).Data.LastOrDefault();
                if (SessionByIdApp != null)
                {
                    SessionsModel.Id = SessionByIdApp.Id;
                    SessionsModel.IsActive = SessionByIdApp.IsActive;
                    IResponse = await SessionsServices.Insert(SessionsModel);
                    return await ResponseSessions(Email, Message, SuscriptionIsValid.MaxSession, IResponse, SessionsModel.Id, IsActive, SessionByIdApp.IsActive);
                }

                SessionsModel.IsActive = true;
                IResponse = await SessionsServices.Insert(SessionsModel);

               --------------> here Exepction.
                SessionByIdApp = (await SessionsServices.ReadByPredicate(p => p.IdApp == IdApp && p.Email == Email)).Data.LastOrDefault();
                return await ResponseSessions(Email, Message, SuscriptionIsValid.MaxSession, IResponse, SessionByIdApp.Id, IsActive, SessionByIdApp.IsActive);

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return null;
            }

        public async Task<IDataResponse<IEnumerable<SessionsModel>>> ReadAsync(Expression<Func<SessionsModel, bool>> predicate)
        {
            IEnumerable<Sessions> resultDto;
            IEnumerable<SessionsModel> result;

            var realmInstance = await _realmManager.GetInstanceAsync();
            if (realmInstance == null)
                return new DataResponse<IEnumerable<SessionsModel>>(null, false, "Realm instance can't be null");

            var afterParameter = Expression.Parameter(typeof(Sessions), predicate.Name);
            var visitor = new ExpressionExtension(predicate, afterParameter);
            var newPredicate = Expression.Lambda<Func<Sessions, bool>>(visitor.Visit(predicate.Body), afterParameter);

            resultDto = realmInstance.All<Sessions>()
                                     .Where(newPredicate);
            result = resultDto.ToModel();

            return new DataResponse<IEnumerable<SessionsModel>>(result, result != null);
        }

Image Exception:
https://ibb.co/fX0q8Hn

Version of Realm and Tooling

  • Realm Object Server Version: ? (you can see this as well in Studio once connected to a Realm instance)
  • Flavor:
    Xamarin

Android & UWP.

Client SDK Version: Realm 10.1.4.
Client OS & Version: Android 9/10. / Windows 10.
Microsoft Visual Studio Community 2019
Version 16.9.6

@papafe
Copy link
Contributor

papafe commented May 26, 2021

Hi @ivanrlg. Does this kind of exception happen only on UWP or also on iOS/Android?
Also, have you maybe tried to use any of the beta versions of Realm? The latest one is version 10.2.0-beta.2.

@nirinchev
Copy link
Member

Can you try removing the .Where clause from resultDto = realmInstance.All<Sessions>().Where(newPredicate);? I can easily imagine that manually created predicate breaking some assumptions in the realm query engine.

@ivanrlg
Copy link
Author

ivanrlg commented May 26, 2021

Hi @ivanrlg. Does this kind of exception happen only on UWP or also on iOS/Android?
Also, have you maybe tried to use any of the beta versions of Realm? The latest one is version 10.2.0-beta.2.

Hi @papafe, this happens in UWP, in Android I think the same although it happens slightly differently. I haven't tried that version, I will and let you know.

@ivanrlg
Copy link
Author

ivanrlg commented May 26, 2021

Can you try removing the .Where clause from resultDto = realmInstance.All<Sessions>().Where(newPredicate);? I can easily imagine that manually created predicate breaking some assumptions in the realm query engine.

Hi @nirinchev, ok I'm going to try as you tell me, I'm curious that it only happens after the first synchronization (when the installation is new) then it doesn't happen.

@ivanrlg
Copy link
Author

ivanrlg commented May 26, 2021

Hi @papafe / @nirinchev probe with version 10.2.0-beta.2 and it keeps giving the same error.

But, I think I figured it out, all this started to know the initial download in the first sync, so comment this code:

OnProgress = progress =>
{
 Debug.WriteLine($"Progress Realm: {progress.TransferredBytes / 1000000} Mb /{progress.TransferableBytes / 1000000} Mb");
}

and vualá, the exception no longer happened.

Again curious that it only happens the first time.

If you wish, you can close the case.

In the same way, I will leave the last message obtained here if I did not comment on the above.

System.InvalidCastException: 'Unable to cast object of type 'System.Object[]' to type 'Realms.Sync.ProgressNotificationToken'.'

This exception was originally thrown at this call stack: Realms.Sync.SessionHandle.HandleSessionProgress(System.IntPtr, ulong, ulong)

@nirinchev
Copy link
Member

Are you by any chance modifying the SyncConfiguration instance used to open the Realm? E.g. is something like that feasible in your code:

this.syncConfig = new SyncConfiguration(...);

public async Task<Realm> GetInstanceAsync()
{
    this.syncConfig.OnProgress = (...);
    return Realm.GetInstanceAsync(this.syncConfig);
};

public Realm GetInstance()
{
    this.syncConfig.OnProgress = null;
    return Realm.GetInstance(this.syncConfig);
}

Asking because I noticed a potential bug where we're not capturing the OnProgress property when GetInstanceAsync is called, which means that modifying it while the Realm is being downloaded might result in unpredictable behavior.

@ivanrlg
Copy link
Author

ivanrlg commented May 27, 2021

Hi @nirinchev , I tried to fix it as you told me but I couldn't do it exactly the same because I don't use GetInstance but it is with "Async".

Perhaps I am committing a bad practice of using your library, but this way I did not get more errors from incorrect threads and the like. I would still like to learn to do it in the best way.

I was able to modify the GetInstanceAsync and it looks like this:

        public async Task<Realms.Realm> GetInstanceAsync()
        {
            Debug.WriteLine($"      In GetInstanceAsync  Time: {DateTime.Now}");

            this.syncConfig.OnProgress = progress =>
            {
                Debug.WriteLine($"Progress Realm: {progress.TransferredBytes / 1000000} Mb /{progress.TransferableBytes / 1000000} Mb");
            };

            return await Realms.Realm.GetInstanceAsync(this.syncConfig);
        }

But sadly I got the exception again.

The thread 0x15d94 has exited with code 0 (0x0).
In GetInstanceAsync Time: 26/5/2021 7:10:15 p. m.
Progress Realm: 19 Mb /19 Mb
Exception thrown: 'System.EntryPointNotFoundException' in Realm.dll
In GetInstanceAsync Time: 26/5/2021 7:10:18 p. m.
Progress Realm: 19 Mb /19 Mb
Exception thrown: 'System.EntryPointNotFoundException' in Realm.dll
Exception thrown: 'System.NullReferenceException' in Realm.dll
Object reference not set to an instance of an object.

@nirinchev
Copy link
Member

Hey @ivanrlg, I'm sorry if I wasn't clear - I wasn't suggesting that this approach would fix things for you, I was just wondering if a pattern like the outlined one is something that may be used in your app. Essentially, I wanted to know if you create a new sync config every time you call Realm.GetInstanceAsync or do you reuse the same config?

@ivanrlg
Copy link
Author

ivanrlg commented May 27, 2021

Hey @nirinchev , I have a LoginRealm method that I only call when the application is started at that moment there I have the new SyncConfig only that time it is executed, then in the Realm.GetInstanceAsync reuse the one already created.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants