umbraco / Umbraco.UIBuilder.Issues

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

Exception thrown: 'System.ApplicationException' in Umbraco.UIBuilder.Infrastructure.dll #94

Closed matt-tolliday-iss closed 5 months ago

matt-tolliday-iss commented 6 months ago

Describe the bug We are seeing a Exception thrown: 'System.ApplicationException' in Umbraco.UIBuilder.Infrastructure.dll when attempting to read an entity from either the repository .Get or .GetAll methods. When using the .GetAll with a lambda, the error is: Exception has been thrown by the target of an invocation.

This code is being executed from within a Umbraco.UIBuilder.Configuration.Actions.Action

at Umbraco.UIBuilder.Persistence.DefaultRepositoryProxy`2.Get(TId id, Boolean raiseEvents) at XXX.XXX.Umbraco.Infrastructure.Register.XXX.Execute(String collectionAlias, Object[] entityIds) in

There are no errors in the Umbraco Logs and there doesn't appear to be anything wrong with the configuration.

The "Status" value was mapped to an enum, which was causing the same error as above under the EventMessages property of the GetAll operationresult (Exception has been thrown by the target of an invocation.)

Model:

[TableName("pbMemberMetaData")]
[PrimaryKey("Id", AutoIncrement = true)]
[ExplicitColumns]
public class MemberMetaDataDto
{
    public int Id { get; set; }

    public int MemberId { get; set; }

    public int Status { get; set; }
}

Database schema:

image

Repository code to call entity:

var entity = repository.GetAll(x => x.MemberId == id);

Expected behavior The entity should be returned from the repository when found by expression.

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

acoumb commented 6 months ago

Hi @matt-tolliday-iss ,

I've tried replicating your configuration using the same table structure, POCO model and with this sample action, but could not replicate the issue:

public class EnquiryAction : UIBuilder.Configuration.Actions.Action<ActionResult>
{
    private readonly IRepositoryFactory _repositoryFactory;

    public EnquiryAction(IRepositoryFactory repositoryFactory) => _repositoryFactory = repositoryFactory;

    public override string Alias => "enquiry-action";

    public override string Name => "Enquiry Action";

    public override bool IsVisible(ActionVisibilityContext ctx)
    {
        return ctx.ActionType == ActionType.Bulk
            || ctx.ActionType == ActionType.Row;
    }

    public override ActionResult Execute(string collectionAlias, object[] entityIds)
    {
        try
        {
            var repo = _repositoryFactory.GetRepository<Enquiry, int>(collectionAlias);

            var result = repo.GetAll(x => x.MemberId == 1055);

            return new ActionResult(true);
        }
        catch (Exception ex)
        {
            return new ActionResult(false, new ActionNotification("Failed to update status", ex.Message));
        }
    }
}

Also called the repository successfully from a test controller:

public class TestController : UmbracoApiController
{
    private readonly IRepositoryFactory _repositoryFactory;

    public TestController(IRepositoryFactory repositoryFactory) => _repositoryFactory = repositoryFactory;

    public IActionResult Index()
    {
        var repository = _repositoryFactory.GetRepository<Enquiry, int>();
        var list = repository.GetAll(x => x.MemberId == 1055);
        return new JsonResult(list);
    }
}

Could you provide more context that could help clarify and replicate the issue?

Thanks, Adrian

matt-tolliday-iss commented 5 months ago

Thanks Adrian,

It's being registered like the following, so that it never technically is visible, but can be "used" with the repository code:

image

Usgae is then like:

image

Variables bind, injected fine:

image

That entity exists in database:

image

Which results in:

image
acoumb commented 5 months ago

Hi @matt-tolliday-iss ,

I eventually managed to catch the exception with this where clause

var result = repo.GetAll(x => x.MemberId == int.Parse(member.Id));

and it was caused by using Parse in a lambda expression (ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'No logic supported for Parse')), so I would recommend not doing that.

This worked instead var result = repo.GetAll(x => x.MemberId.Equals(member.Id));.

With your sample code it worked fine though. image

acoumb commented 5 months ago

Closing this for now, will re-open if the matter persists.