umco / umbraco-ditto

Ditto - the friendly view-model mapper for Umbraco
http://our.umbraco.org/projects/developer-tools/ditto
MIT License
79 stars 33 forks source link

Orphaned Archetype Properties Cause Null Exception During Mapping #221

Closed Nicholas-Westby closed 7 years ago

Nicholas-Westby commented 7 years ago

Here's a full stack trace:

Stack Trace Showing Exception During Ditto Mapping

This same error happens whenever I've created an Archetype fieldset on a content node, then I rename a property within that fieldset, then I visit the page again (which will cause the Archetype fieldset on that page to be mapped by Ditto).

In short, it seems like the property still exists in the content section even though it no longer exists in the Archetype fieldset model.

Some sort of interplay between the Umbraco core, Archetype, and Ditto does not seem to like this. My preference would be for any orphaned data to be ignored (i.e., not throw an exception). If you feel this issue is more appropriate for the Archetype or Umbraco core issue trackers, let me know. I figured I'd start here since it's during the Ditto mapping operation that I run into the issue.

While it's probably not particularly helpful, I'll give you a concrete example to make it clear where I'm experiencing this issue. I have an Archetype that has a few dozen fieldsets (one for each widget on my site). Here is the fieldset definition for one widget in particular, Icon Callout Grid:

Icon Callout Grid

The "header" property is where I ran into issues. I renamed it from "Label (Ignored)" to "Header". There was already an instance of this fieldset created on a content node, so it still had a property with an alias of "labelIgnored" (even though you can see it visually since Archetype doesn't display properties that don't exist in the fieldset definition). Here's what the data looks like (extracted from the umbraco.config file) for the widgets (I removed all the widgets except the problematic one):

{
    "fieldsets": [
    {
        "properties": [{
            "alias": "labelIgnored",
            "value": "sdfggga"
        },
        {
            "alias": "callouts",
            "value": "{\"fieldsets\":[{\"properties\":[{\"alias\":\"header\",\"value\":\"<p>Item 1</p>\"},{\"alias\":\"summary\",\"value\":\"<p>The summary for item 1.</p>\"},{\"alias\":\"link\",\"value\":\"{\\\"fieldsets\\\":[{\\\"properties\\\":[{\\\"alias\\\":\\\"linkLabel\\\",\\\"value\\\":\\\"Something\\\"},{\\\"alias\\\":\\\"linkTitle\\\",\\\"value\\\":\\\"Something\\\"},{\\\"alias\\\":\\\"linkSuffix\\\",\\\"value\\\":\\\"\\\"},{\\\"alias\\\":\\\"newWindow\\\",\\\"value\\\":\\\"0\\\"},{\\\"alias\\\":\\\"linkPage\\\",\\\"value\\\":\\\"1052\\\"}],\\\"alias\\\":\\\"contentLink\\\",\\\"disabled\\\":false,\\\"id\\\":\\\"60c029e5-0e90-4b18-a34e-36133fdc9be2\\\",\\\"releaseDate\\\":null,\\\"expireDate\\\":null,\\\"allowedMemberGroups\\\":\\\"\\\"}]}\"},{\"alias\":\"icon\",\"value\":\"fa-adn\"}],\"alias\":\"iconCalloutItem\",\"disabled\":false,\"id\":\"18401925-36cb-4afb-972a-5090e7d67728\",\"releaseDate\":null,\"expireDate\":null,\"allowedMemberGroups\":\"\"}]}"
        },
        {
            "alias": "header",
            "value": "<p>The Header</p>"
        },
        {
            "alias": "subheader",
            "value": "<p>The Subheader</p>"
        },
        {
            "alias": "summary",
            "value": "<p>The Summary</p>"
        }],
        "alias": "iconCalloutGrid",
        "disabled": false,
        "id": "3c2ede68-f6a9-49c9-94dd-f5bf1ba8f110",
        "releaseDate": null,
        "expireDate": null,
        "allowedMemberGroups": ""
    }]
}

Note the first property of "labelIgnored". That's the one causing issues, as it's orphaned and the mapping process doesn't seem to like that.

EDIT: Umbraco 7.6.4. Archetype 1.14.1. Ditto 0.11.0.

Nicholas-Westby commented 7 years ago

By the way, here is the code for the DittoArchetypeAttribute that is mentioned in the stack trace: https://github.com/rhythmagency/rhythm.umbraco.ditto.archetype/blob/master/src/Rhythm.Umbraco.Ditto.Archetype/Processors/DittoArchetypeAttribute.cs

It is now also part of Ditto Labs: https://github.com/leekelleher/umbraco-ditto-labs/blob/develop/src/Our.Umbraco.Ditto.Archetype/ComponentModel/Processors/DittoArchetypeAttribute.cs

leekelleher commented 7 years ago

@Nicholas-Westby - thanks for raising this ... it's definitely an Archetype issue.

As you've seen, when fieldset property-alias is renamed, Archetype doesn't tidy up after itself. (I'm not sure how it would do that, but that's a different topic). So the existing value for the previous property-alias still remains in the JSON, (again as you've seen).

The problem is then with ArchetypeFieldsetModel, as the "properties" JSON is deserialized to the Properties property, (see here).

So then, when the ArchetypePublishedContent model is being constructed, all of the properties are wrapped in a ArchetypePublishedProperty, (see here), which needs to fake an Umbraco PublishedPropertyType for it, (see here). Which is where I think the YSoD occurs.

Right now, I'm not sure what would be the best course of action to resolve that issue. Whether Archetype should attempt to clean up any orphaned property-values, or whether the deserialization to ArchetypeFieldsetModel should ensure the property-alias is valid. Either way, it's definitely an Archetype issue, not Ditto.

Nicholas-Westby commented 7 years ago

That sounds right. Thanks for the quick response @leekelleher. I have created an issue in the Archetype issue tracker: https://github.com/kgiszewski/Archetype/issues/418

Closing this ticket since it's not really a Ditto issue.