uSync icon indicating copy to clipboard operation
uSync copied to clipboard

uSync Fails to create export file after contentService.SaveAndPublish event

Open craigs100 opened this issue 2 years ago • 3 comments

Describe the bug In a custom Umbraco Forms workflow, form parameters are used to create a new Umbraco content node via the ContentService.SaveAndPublish(myPage). This happens successfully. On completion of the task there is a Warning from uSync in the terminal:-

[11:41:01 INF] Form Entry Submitted - Form Entry Id: db11390a-ff13-4e0d-8715-6fca2bc6108a, Form Id: 5e589837-7070-4c8c-8c83-86b28df1f129, User: [11:41:03 INF] Document MyNewPage (id=0) has been published. [11:41:03 INF] Form Entry Approved - Form Entry Id: db11390a-ff13-4e0d-8715-6fca2bc6108a, Form Id: 5e589837-7070-4c8c-8c83-86b28df1f129, User: [11:41:03 WRN] Failed to create uSync export file System.ArgumentNullException: Value cannot be null. (Parameter 'value') at System.ArgumentNullException.Throw(String paramName) at System.Xml.Linq.XCData..ctor(String value) at uSync.Core.Serialization.Serializers.ContentSerializerBase1.SerializeProperties(TObject item, SyncSerializerOptions options) at uSync.Core.Serialization.Serializers.ContentSerializer.SerializeCore(IContent item, SyncSerializerOptions options) at uSync.Core.Serialization.SyncSerializerRoot1.Serialize(TObject item, SyncSerializerOptions options) at uSync.BackOffice.SyncHandlers.SyncHandlerRoot2.SerializeItem(TObject item, SyncSerializerOptions options) at uSync.BackOffice.SyncHandlers.SyncHandlerRoot2.Export_DoExport(TObject item, String filename, String[] folders, HandlerSettings config) at uSync.BackOffice.SyncHandlers.SyncHandlerRoot2.Export(TObject item, String[] folders, HandlerSettings config) at uSync.BackOffice.SyncHandlers.SyncHandlerRoot2.Handle(SavedNotification`1 notification)

To Reproduce Steps to reproduce the behavior: Create a custom UmbracoForms workflow that creates a new node. Apply it to a form and submit the form.

Expected behavior No warnings in Terminal on completion

Screenshots See terminal readout above.

About your Site (please complete the following information):

  • Umbraco Version: 13.2.2
  • uSync Version: v13.1.3 + FormsEdition (v13.0.0.0)
  • Browser Brave

Additional context When uSync is removed from the project, the workflow completes without error.

I have the sneakiest suspicion it's something to do with the cache not yet being updated after the SaveAndPublish.

craigs100 avatar Apr 10 '24 10:04 craigs100

Hi,

Are there any custom properties inside the content item you are creating ? . I suspect its not the fact that the item is being created in umbraco forms, but that there is something we are not catching when one (or more) of the properties is being created.

i think its this line.,

https://github.com/KevinJump/uSync/blob/b14a9e93214b6f51e703adf52a3c2c45a66f7296/uSync.Core/Serialization/Serializers/ContentSerializerBase.cs#L261

that gets the value from the GetExportValue method:

https://github.com/KevinJump/uSync/blob/v13/main/uSync.Core/Serialization/Serializers/ContentSerializerBase.cs#L652-L670

which in turn is getting it from a sync value mapper.

https://github.com/KevinJump/uSync/blob/v13/main/uSync.Core/Mapping/SyncValueMapperCollection.cs#L45-L62

and that value is returning a string when the value is null,

so i think the value isn't null, but then a mapper for some reason is returning null, 🤔

  • so any information on the properties that are being set in the content item would help us work that out.

KevinJump avatar Apr 10 '24 11:04 KevinJump

Looking at the code I suspect this is an edge case where a non-empty but whitespace string is set as the value of something like nested content or blocklist then the mapper code for those values will return null, (when it should return an empty string).

that would be a simple fix

but if we can confirm the properties on your content node we can test this better.

KevinJump avatar Apr 10 '24 11:04 KevinJump

Sorry for the delay, just had an hour long phone call. Here's the code that creates and saves(and publishes) the new node.


        // Get Magic Number
        int magicNumber = _miscHelpers.GetNextMagicNumber();

        // Advertiser List Root Id
        var companyName = context.Record.GetRecordFieldByAlias("companyName")?.ValuesAsString(false);
        bool isProductionEnv = _configuration["ASPNETCORE_ENVIRONMENT"] == "Production";
        if (!isProductionEnv) {
            companyName = "TEST - " + companyName;
        }

        int advertiserListNodeID = _miscHelpers.GetAdvertiserListListNode().Id;

        IContent advertiserPage = _contentService.Create(companyName, advertiserListNodeID, "advertiserPage");

        List<string> imageList = new List<string>();

        ////////////////////////////////////////////////////////////
        // Names need to be max 12 chars - Legacy System limitation!
        ////////////////////////////////////////////////////////////

        advertiserPage.Properties["address1"]?.SetValue(context.Record.GetRecordFieldByAlias("address1")?.ValuesAsString(false));
        advertiserPage.Properties["address2"]?.SetValue(context.Record.GetRecordFieldByAlias("address2")?.ValuesAsString(false));
        advertiserPage.Properties["town"]?.SetValue(context.Record.GetRecordFieldByAlias("town")?.ValuesAsString(false));
        advertiserPage.Properties["county"]?.SetValue(context.Record.GetRecordFieldByAlias("county")?.ValuesAsString(false));
        advertiserPage.Properties["postcode"]?.SetValue(context.Record.GetRecordFieldByAlias("postcode")?.ValuesAsString(false));
        advertiserPage.Properties["companyDesc"]?.SetValue(context.Record.GetRecordFieldByAlias("companyDesc")?.ValuesAsString(false));
        advertiserPage.Properties["dataConsent"]?.SetValue(context.Record.GetRecordFieldByAlias("dataConsent")?.ValuesAsString(false) == "True");
        advertiserPage.Properties["magicNum"]?.SetValue(magicNumber);

        // SEO
        advertiserPage.Properties["metaTitle"]?.SetValue(context.Record.GetRecordFieldByAlias("companyName")?.ValuesAsString(false));
        advertiserPage.Properties["disableIndexing"]?.SetValue(false);
        advertiserPage.Properties["disableSiteMapEntry"]?.SetValue(false);

        // Upload images
        imageList.Add(context.Record.GetRecordFieldByAlias("logo")?.ValuesAsString(false));
        string logoMedia = _importMedia.GetMedia(imageList, companyName, magicNumber, true);
        imageList.Clear();

        var AdditionalImagesUploadedPathsArray = context.Record.GetRecordFieldByAlias("addtnlImages")?.ValuesAsString(false).Split(",", StringSplitOptions.TrimEntries);
        foreach (string imagePath in AdditionalImagesUploadedPathsArray) {
            imageList.Add(imagePath);
        }

        string additionalMedia = _importMedia.GetMedia(imageList, companyName, magicNumber, false);
        imageList.Clear();

        advertiserPage.Properties["logoImage"]?.SetValue(logoMedia);
        advertiserPage.Properties["addtnlImages"]?.SetValue(additionalMedia);

        // Get List Image
        string listImage = additionalMedia.Split(",")[0];
        advertiserPage.Properties["listImage"]?.SetValue(listImage);

        // Save and Publish Page
        PublishResult pageRef = null;
        try {
            pageRef = _contentService.SaveAndPublish(advertiserPage);
        }
        catch (Exception ex) {
            _logger.LogInformation("Error Saving new Advertiser: {companyName}", context.Record.GetRecordFieldByAlias("companyName")?.ValuesAsString(false));
            // Send email
            _miscHelpers.ExceptionEmailHelper(ex);
        }```
        
        This all gets saved properly, so not sure what would give uSync an issue.
        
        The pageRef variable is just a hook to access the saved pages ID for transmission to an API.

craigs100 avatar Apr 10 '24 12:04 craigs100

I think this too is fixed in v13.2 of forms.

KevinJump avatar Apr 22 '24 13:04 KevinJump

Tested, all good, thanks :)

craigs100 avatar Apr 22 '24 14:04 craigs100