umbraco / Umbraco.UIBuilder.Issues

Back office UI builder for Umbraco
3 stars 2 forks source link

Tree alias not found when adding virtual sub tree to Vendr Store #53

Open philipdanielhayton opened 1 year ago

philipdanielhayton commented 1 year ago

Describe the bug Adding a VirtualSubTree to a store in Vendr throws a Could not retrieve tree alias exception (full trace log below). I've tested this on two separate projects running Umbraco 10.3.2 and 11.2.0 and it happens on both.

Steps To Reproduce Steps to reproduce the behavior:

  1. Setup project with Vendr and Konstrukt installed
  2. Add the code below to the startup class
  3. Navigate to any store within Vendr and expand it's tree
  4. See error (I've attached it below, beneath the code block)

Expected behavior I expected the node to be appended to the Store subtree, like this example.

Environment (please complete the following information):

                .AddKonstrukt(k =>
                {
                    k.WithSection("commerce", sectionConfig => sectionConfig
                        .WithTree("vendr", treeConfig => treeConfig
                            .AddVirtualSubTreeAfter(ctx => Guid.TryParse(ctx.Source.Id, out _), tn => tn.Name == "Analytics", virtualTreeConfig => virtualTreeConfig
                                .AddCollection<Notification>(x => x.Id, x => x.StoreId, "Notification", "Notifications", "A product notification", "icon-bell", "icon-bell", collectionConfig => collectionConfig
                                    .SetNameFormat(p => p.Email)
                                    .SetDateCreatedProperty(x => x.DateCreated)
                                    .DisableCreate()
                                    .AddDataView("Pending", x => x.Status == NotificationStatus.Pending)
                                    .AddDataView("Notified", x => x.Status == NotificationStatus.Notified)
                                    .Editor(editorConfig => editorConfig
                                        .AddTab("General", tabConfig => tabConfig
                                            .Sidebar(sidebarConfig => sidebarConfig
                                                .AddFieldset("Info", fieldsetConfig => fieldsetConfig
                                                    .AddField(p => p.DateCreated).MakeReadOnly()
                                                )
                                            )
                                            .AddFieldset("General", fieldsetConfig => fieldsetConfig
                                                .AddField(p => p.ProductReference).SetDataType("Product Picker")
                                                .AddField(p => p.Email).SetValidationRegex("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+")
                                                .AddField(p => p.Status).SetDataType("Notification Status")
                                            )
                                        )
                                    )
                                )
                            )

                        )
                    );
                })
at Umbraco.Deploy.UI.Tree.TreeIntegration.GetTreeAlias(String treeAliasFromNotification, FormCollection queryString)
   at Umbraco.Deploy.UI.Tree.TreeIntegration.UpdateNodesForDeploy(TreeNodesRenderingNotification notification)
   at Umbraco.Deploy.UI.Tree.TreeIntegrationNotificationHandler.Handle(TreeNodesRenderingNotification notification)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishCore(IEnumerable`1 allHandlers, INotification notification)
   at Umbraco.Cms.Core.Events.NotificationHandlerWrapperImpl`1.Handle(INotification notification, ServiceFactory serviceFactory, Action`2 publish)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishAsync[TNotification](TNotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Web.BackOffice.Trees.TreeControllerBase.GetNodes(String id, FormCollection queryStrings)
   at Konstrukt.Web.Events.Handlers.InjectKonstruktVirtualSubTrees.<>c__DisplayClass8_0.<<HandleAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Konstrukt.ScopedExecutionContext.ExecuteAsync(Func`3 action, CancellationToken cancellationToken)
   at Konstrukt.Web.Events.Handlers.InjectKonstruktVirtualSubTrees.HandleAsync(TreeNodesRenderingNotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishCoreAsync(IEnumerable`1 allHandlers, INotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Web.BackOffice.Trees.TreeControllerBase.GetNodes(String id, FormCollection queryStrings)
   at lambda_method1131(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

This item has been added to our backlog AB#34771

mattbrailsford commented 1 year ago

Ok, so by the stack trace this looks like it's actually coming from Umbraco Deploy and not Konstrukt 🤔 (or at least Umbraco Deploy is causing some conflict)

philipdanielhayton commented 1 year ago

Let me disable deploy and test... deploy causes so many issues for me 🤦🏻‍♂️

philipdanielhayton commented 1 year ago

Yup, that's fixed it. 🤷🏻‍♂️ Sorry, I'll raise a bug with Umbraco deploy instead.

mattbrailsford commented 1 year ago

Would be good to know what you find out either way

philipdanielhayton commented 1 year ago

Just for info:

https://github.com/umbraco/Umbraco.Deploy.Issues/issues/160

AndyButland commented 1 year ago

Hi @philipdanielhayton and @mattbrailsford - I've just started looking into this issue this morning. We're getting an error in Deploy in our tree rendering notification handler (which is used to add context menus for "queue for transfer", "restore" etc.).

It's expecting trees to have an alias, and the exception is being thrown when it doesn't find one.

I'm going to look to see if we can just gracefully ignore such trees in this case, which should be straightforward enough.

However, I looked at a workaround, as I figured if you set an alias there wouldn't be an issue. So I updated the above code to:

  ...
  .WithTree("vendr", treeConfig => treeConfig
      .SetAlias("assets")
      .AddVirtualSubTreeAfter(ctx => Guid.TryParse(ctx.Source.Id, out _), tn => tn.Name == "Analytics", virtualTreeConfig => virtualTreeConfig
          .AddCollection<Notification>(x => x.Id, x => x.StoreId, "Notification", "Notifications", "A product notification", "icon-bell", "icon-bell", ...

But even with that, the tree alias that is provided by the notification is still null.

So there might be an issue in Konstrukt too here, in that even if an alias is set, it's not passed in the TreeNodesRenderingNotification?

mattbrailsford commented 1 year ago

Thanks Andy for your insight. I’ll take a look this morning to see if there is something we have neglected to pass through. Much easier now I know where to be looking 👍🏻

mattbrailsford commented 1 year ago

Ok, I think I've implemented something that should work. You can find a 1.6.5-beta001 on our unstable nuget feed at https://nuget.outfield.digital/unstable/v3/index.json if you want to test.

jemayn commented 1 year ago

Hey @mattbrailsford

Just wanted to chime in here - I ran into the same issue today on a pretty empty v11 Cloud site where I set up Konstrukt. I had this basic config:

builder.AddSection("Admin Section", sectionConfig => sectionConfig
                .Tree(treeConfig => treeConfig
                    .SetAlias("orders")
                    .AddCollection<Orders>(x => x.Id, "Order", "Orders", "Incoming book orders", "icon-book", "icon-books", collectionConfig => collectionConfig
                        .SetNameProperty(p => p.FullName)))

Which gave this error whenever I hit the backoffice: image

This was on the following versions: Umbraco 11.2.0 Konstrukt 1.6.4 Deploy 11.0.1

I tried to grab the 1.6.5-beta001, did a full rebuild but I still hit the same error. Let me know if there is anything I can do to help test or debug further!

mattbrailsford commented 1 year ago

Are you able to see in dev tools the exact URL with query parameters that is failing?

jemayn commented 1 year ago

Looks to fail on this call: image

Doesn't seem to pass along any query params.

Gets this response:

{
    "ExceptionMessage": "Could not retrieve tree alias.",
    "ExceptionType": "System.InvalidOperationException, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
    "StackTrace":"   at Umbraco.Deploy.UI.Tree.TreeIntegration.GetTreeAlias(String treeAliasFromNotification, FormCollection queryString)
   at Umbraco.Deploy.UI.Tree.TreeIntegration.UpdateNodesForDeploy(TreeNodesRenderingNotification notification)
   at Umbraco.Deploy.UI.Tree.TreeIntegrationNotificationHandler.Handle(TreeNodesRenderingNotification notification)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishCore(IEnumerable`1 allHandlers, INotification notification)
   at Umbraco.Cms.Core.Events.NotificationHandlerWrapperImpl`1.Handle(INotification notification, ServiceFactory serviceFactory, Action`2 publish)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishAsync[TNotification
    ](TNotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Web.BackOffice.Trees.TreeControllerBase.GetNodes(String id, FormCollection queryStrings)
   at Umbraco.Cms.Web.BackOffice.Trees.ApplicationTreeController.GetChildren(Tree tree, Int32 id, FormCollection querystring)
   at Umbraco.Cms.Web.BackOffice.Trees.ApplicationTreeController.GetTreeRootNode(Tree tree, Int32 id, FormCollection querystring)
   at Umbraco.Cms.Web.BackOffice.Trees.ApplicationTreeController.GetApplicationTrees(String application, String tree, FormCollection queryStrings, TreeUse use)
   at Umbraco.Cms.Web.BackOffice.Controllers.SectionController.GetSections()
   at lambda_method193(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)"}
mattbrailsford commented 1 year ago

Hmm, if I upgrade to the beta it seems to work on my test Cloud install 🤔

jemayn commented 1 year ago

@mattbrailsford I am unfortunately still seeing it. May just have to wait for deploy 11.0.2 then to see if that does the trick, since the exception is thrown there..

acoumb commented 4 months ago

Hi @philipdanielhayton , @jemayn ,

Could you give me an update on this, is this still an issue for you in working with Umbraco.Commerce and Umbraco.UIBuilder, or experience other related issue?

Thank you, Adrian

philipdanielhayton commented 4 months ago

Hi @acoumb,

I'm back on this project next week so I'll give it another try then, will let you know the outcome.

Kind regards

Phil

acoumb commented 4 months ago

Hi @philipdanielhayton ,

Could you tell me if you have any updates on this?

Thanks, Adrian