Blazored / LocalStorage

A library to provide access to local storage in Blazor applications
https://blazored.github.io/LocalStorage/
MIT License
1.2k stars 118 forks source link

[Bug] LocalStorage crashes without throwing exception #219

Open sponsorrockit opened 1 year ago

sponsorrockit commented 1 year ago

Describe the bug local storage crashes with no exception thrown. Was working fine until today. Suddenly stopped working without changes to code.

To Reproduce Using SignalIR Blazor Server .Net 7

Any attempt to Get or Set item async crashes, stops all processing without error in jscript or error in blazor server. await localStorage.GetItemAsync("systemUser"); await localStorage.SetItemAsync("systemUser", systemUser);

Expected behavior An error message or exception

Hosting Model (is this issue happening with a certain hosting model?):

Additional context No Exception thrown, just stops all processing in OnAfterRenderAsync and OnInitializedAsync Had to comment all lcoal storage uses: Was working fine until today then stopped without posting any code changes. @inject ILocalStorageService localStorage // try // {

// await localStorage.SetItemAsync("systemUser", systemUser); // } // catch (Exception e) // { // } Screenshot 2023-08-23 15 06 51

sponsorrockit commented 1 year ago

Browser details - no local storage error thrown just a disconnect from blazor server Localstoragerror

chrissainty commented 1 year ago

Hey @sponsorrockit, can you provide a minimal repro project, the package is working fine as far as a I can see testing on the sample projects and in a fresh project.

sponsorrockit commented 1 year ago

I'll try to put something together by end of week for you to test with. Thanks, sm

[cid:ff9653af-ddd2-4624-b63a-98d85e7a68a1]

Steve McRae

Sponsorship Manager Sponsor Rock It, Inc.

M: +1(858)255-0243


From: Chris Sainty @.> Sent: Wednesday, August 23, 2023 10:39 PM To: Blazored/LocalStorage @.> Cc: Steve McRae @.>; Mention @.> Subject: Re: [Blazored/LocalStorage] [Bug] LocalStorage crashes without throwing exception (Issue #219)

Hey @sponsorrockithttps://github.com/sponsorrockit, can you provide a minimal repro project, the package is working fine as far as a I can see testing on the sample projects and in a fresh project.

— Reply to this email directly, view it on GitHubhttps://github.com/Blazored/LocalStorage/issues/219#issuecomment-1691035742, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AX5I3ASEYVUFWXVXG6ULZW3XW3SK7ANCNFSM6AAAAAA34DTEXA. You are receiving this because you were mentioned.Message ID: @.***>

sponsorrockit commented 1 year ago

Hey Chris, Thanks for taking the time to review.

I have narrowed it down with some testing to be the following error that does not throw an exception.

Save an object to local storage. Modify the object code (add property) Try to read the original object stored - Crash Try to write the new object over the old object - Crash. Delete the old object then write the new object - no Crash. Change the name of the new object and write the object - no crash.

The Staff class has lots of methods and properties with arrays, lists, Enums, annotations, etc. and I was storing this complex object. The object relies on 30+ other objects (e.g. orders, activities, etc.) so to share this I would have to share my entire domain, something I'm not prepared to do right now.

Serialization with text.Json worked on the object by itself ok so not sure where the issue presents.

It worked fine until recently. I'm not sure exactly what change caused the failure, so I have now switched to storing just a string and it works ok.

I created a test project with simplified object from Json and it worked ok as well. So it has something to do with one or more of the child objects. I think it may be my Order class that is also a complex object.

I was storing the staff object ok. Then made changes to the staff object. Browser has a staff object already in local storage. Then when trying to write the staff object again it crashes no exception.

So I removed the recently added properties and methods from the staff object. Created a new staffX class and changed the key. It worked.

So then I went back and using the complex staff class just changed the key name and that worked.

So the problem has to do with

I also had a fail when I wrote the staffX object ok then tried to re-write the object with same key and it fails. but if I change the key it writes ok.

Deleting the complex Staff object from the browser allows the first time write ok. Renaming the key worked as well.

So I've re-written the code the look for the key and remove the object before trying the write it and that worked.

Again the issue I see is it does not throw exception and it stops the processing.

        try
        {
            await localStorage.SetItemAsync<string>("loginEmail", loginEmail); // this worked ok no issue

            // serialize the systemUser to local storage
            //var json = System.Text.Json.JsonSerializer.Serialize(systemUser); // this worked ok no issue

var sx = new StaffX() await localStorage.SetItemAsync("systemUserx", sx); // changing the name of the key worked.

       // systemUser already exists in browser with old Staff class // var simpleSystemUser = new Staff(); // testing empty staff // await localStorage.SetItemAsync("systemUser", simpleSystemUser); // fails - no exception // await localStorage.SetItemAsync("systemUser", systemUser); // fails - no exception

        }
        catch (Exception e)
        {

        }

Hope this helps. Thanks, Steve

[cid:02211632-0d6a-47f6-9fbf-91209ac91100]

Steve McRae

Sponsorship Manager Sponsor Rock It, Inc.

M: +1(858)255-0243


From: Chris Sainty @.> Sent: Wednesday, August 23, 2023 10:39 PM To: Blazored/LocalStorage @.> Cc: Steve McRae @.>; Mention @.> Subject: Re: [Blazored/LocalStorage] [Bug] LocalStorage crashes without throwing exception (Issue #219)

Hey @sponsorrockithttps://github.com/sponsorrockit, can you provide a minimal repro project, the package is working fine as far as a I can see testing on the sample projects and in a fresh project.

— Reply to this email directly, view it on GitHubhttps://github.com/Blazored/LocalStorage/issues/219#issuecomment-1691035742, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AX5I3ASEYVUFWXVXG6ULZW3XW3SK7ANCNFSM6AAAAAA34DTEXA. You are receiving this because you were mentioned.Message ID: @.***>

chrissainty commented 10 months ago

Thanks for the detailed explanation @sponsorrockit.

Just to clarify, are you putting an object into local storage that contains 30+ other objects (your whole domain pretty much)? Just that you said you weren't happy sharing them here but anyone who uses your app will be able to get hold of them.

In terms of the issue you're seeing, it sounds like it might be a System.Text.Json problem. If you're saving one structure and then changing that structure and attempting to read it out again, it might need some extra configuration to handle that. It's not as forgiving as Newtonsoft JSON is. Have you tried adjusting the serialiser?

julianadormon commented 8 months ago

I am having a similar issue trying
var StoredFormModels = await LocalStorage.GetItemAsync<List>("Forms");

I have not been able to narrow it down yet, however what is truly the bigger issue is that even though this is wrapped in a try/catch, it never reaches the catch.

It simply fails silently and causes the web socket to refresh. No errors in console or server.

julianadormon commented 7 months ago

@chrissainty I'm not sure if you had a chance to review my comment above. Any ideas on how we can get this to fail properly?

`async void SaveFormLocally() { try { if (PageVm.FormPageVm == null) return;

        PageVm.FormPageVm.CustomFormSubmission.DateSubmitted = DateTime.UtcNow;

        PageVm.FormPageVm.CustomFormSubmission.CustomFormId = PageVm.FormPageVm.CustomForm.CustomFormId;

        var StoredFormModels = await LocalStorage.GetItemAsync<List<CustomFormSubmission>>("ProofpixForms");

        if (StoredFormModels != null)
        {
            if (StoredFormModels.Any(x => x.CustomForm.CustomFormId == PageVm.FormPageVm.CustomFormSubmission.CustomForm.CustomFormId))
            {
                var StoredCustomFormSubmission = StoredFormModels.FirstOrDefault(x => x.CustomForm.CustomFormId == PageVm.FormPageVm.CustomFormSubmission.CustomForm.CustomFormId);

                if (StoredCustomFormSubmission != null)
                {
                    StoredFormModels.Remove(StoredCustomFormSubmission);
                }

                StoredFormModels.Add(PageVm.FormPageVm.CustomFormSubmission);
            }
            else
            {
                StoredFormModels.Add(PageVm.FormPageVm.CustomFormSubmission);
            }
        }
        else
        {
            StoredFormModels = new List<CustomFormSubmission> { PageVm.FormPageVm.CustomFormSubmission };
        }

        await LocalStorage.SetItemAsync("ProofpixForms", StoredFormModels);
    }
    catch (Exception Ex)
    {
        Console.WriteLine(Ex.ToString());
    }
}`
adamhearn commented 7 months ago

@chrissainty .NET 8 Blazor wasm only project (bumped from and was working with 6) with the same issue as described. The version of LocalStorage is the same (4.4.0). Browser is Edge latest on Windows 10.

The call it gets down to is:

BrowserStorageProvider::GetItemAsync
return await _jsRuntime.InvokeAsync<string>("localStorage.getItem", cancellationToken, key);

Nothing raised, nothing logged in VS or the browser console just hangs there seemingly forever.

adamhearn commented 7 months ago

Also, swapped out this library for another and it exhibited the exact same issue. If it wasn't already obvious it's safe to say that it's a .NET 8 wasm issue rather than an issue with this library.

julianadormon commented 7 months ago

I'm using Blazer Server .net 7 with System.Text.Json. I ended up saving my data as strings and then serialize those to avoid the issue. Seems to be working so far.

julianadormon commented 7 months ago

Actually, I take that back. I am getting a socket reset with no error now calling: var StoredFormStrings = await LocalStorage.GetItemAsync<List>("ProofpixForms");

panoukos41 commented 6 months ago

After coming across this issue and having the same problem myself in Blazor Server .NET 6.0 & lib version 4.3.0 I get no exception and the connection just resets.

It must have something to do with the object size. Although the object ends up in the storage the connection just crushes. When I reduced the size of my object it worked fine. It didn't matter if I used the AsString or serialized it to a string myself.

chrissainty commented 6 months ago

For Blazor Server, some people could be hitting the default limit of the SignalR connection. It's worth trying to up that and see if that cures the issues.

panoukos41 commented 5 months ago

@chrissainty yes for server increasing the limit fixed the problem thanks.