Open glenntKF opened 3 years ago
Hello @glenntKF It would be very helpful if you provide a test that can reproduce the bug.
Hi @zjklee,
Thanks for the quick reply. Upon further testing it looks like it doesn't have anything to do with nested loops. It occurs in a loop where the JSON being iterated on is an array with values in it:
{
"items": [
"value1",
"value2"
]
}
Below is a test case. We are using .net 5 core.
[Fact]
public void Handlebars_EachPartialError()
{
// Arrange
string jsonString = @"{
""items"": [
""item1"",
""item2""
]
}";
JsonDocument json = JsonSerializer.Deserialize<JsonDocument>(jsonString);
IHandlebars handlebars = HandlebarsDotNet.Handlebars.Create();
handlebars.Configuration.UseJson();
string template = @"
This is a template
{{> local/myPartial value=""test partial value""}}
{{#each items}}
{{name}}
{{> local/myPartial value=name}}
{{/#each}}";
handlebars.RegisterTemplate("local/myPartial", "This is a value {{value}}");
var compiledTemplate = handlebars.Compile(template);
var result = compiledTemplate(json);
Assert.Equal("", "");
}
If I wrap the values in the array with objects it works fine:
{
"items": [
{
"value": "value1"
},
{
"value": "value2"
}
]
}
Thanks.
Describe the bug
Hi, we have started using Handlebars.net and it is a great library. We are running into an issue where using named arguments in a partial when in a nested loop causes an error. We are using a JsonDocument from System.Text.Json as the model for the template.
Expected behavior:
Partials in nested loops with named arguments should not cause errors when used.
Test to reproduce
{{#each items }} {{#each this.nested}} {{> myPartial arg1=value1 arg2=value2 }} {{/each} {{/each}}
Other related info
Stack trace HandlebarsDotNet.HandlebarsRuntimeException: Runtime error while rendering partial 'local/details', see inner exception for more information ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. at HandlebarsDotNet.Extension.Json.Utils.GetEnumerator(JsonElement document) at HandlebarsDotNet.BindingContext.PopulateHash(HashParameterDictionary hash, Object from) at HandlebarsDotNet.BindingContext.Initialize() at HandlebarsDotNet.BindingContext.BindingContextPool.CreateContext(ICompiledHandlebarsConfiguration configuration, Object value, BindingContext parent, TemplateDelegate partialBlockTemplate) at lambda_method240(Closure , EncodedTextWriter& , BindingContext ) at HandlebarsDotNet.Extension.Json.JsonElementIterator.IterateArray(EncodedTextWriter& writer, BindingContext context, ChainSegment[] blockParamsVariables, JsonElement target, TemplateDelegate template, TemplateDelegate ifEmpty) at HandlebarsDotNet.Extension.Json.JsonElementIterator.HandlebarsDotNet.Iterators.IIterator.Iterate(EncodedTextWriter& writer, BindingContext context, ChainSegment[] blockParamsVariables, Object input, TemplateDelegate template, TemplateDelegate ifEmpty) at HandlebarsDotNet.Compiler.Iterator.Iterate(BindingContext context, EncodedTextWriter writer, ChainSegment[] blockParamsVariables, Object target, TemplateDelegate template, TemplateDelegate ifEmpty) at lambda_method241(Closure , EncodedTextWriter& , BindingContext ) at HandlebarsDotNet.Extension.Json.JsonElementIterator.IterateArray(EncodedTextWriter& writer, BindingContext context, ChainSegment[] blockParamsVariables, JsonElement target, TemplateDelegate template, TemplateDelegate ifEmpty) at HandlebarsDotNet.Extension.Json.JsonElementIterator.HandlebarsDotNet.Iterators.IIterator.Iterate(EncodedTextWriter& writer, BindingContext context, ChainSegment[] blockParamsVariables, Object input, TemplateDelegate template, TemplateDelegate ifEmpty) at HandlebarsDotNet.Compiler.Iterator.Iterate(BindingContext context, EncodedTextWriter writer, ChainSegment[] blockParamsVariables, Object target, TemplateDelegate template, TemplateDelegate ifEmpty) at lambda_method242(Closure , EncodedTextWriter& , BindingContext ) at HandlebarsDotNet.HandlebarsEnvironment.<>cDisplayClass15_0.b__0(TextWriter writer, Object context, Object data)
at HandlebarsDotNet.Compiler.PartialBinder.InvokePartial(String partialName, BindingContext context, EncodedTextWriter writer, ICompiledHandlebarsConfiguration configuration)
--- End of inner exception stack trace ---
at HandlebarsDotNet.Compiler.PartialBinder.InvokePartial(String partialName, BindingContext context, EncodedTextWriter writer, ICompiledHandlebarsConfiguration configuration)
at HandlebarsDotNet.Compiler.PartialBinder.InvokePartialWithFallback(String partialName, BindingContext context, EncodedTextWriter writer, ICompiledHandlebarsConfiguration configuration)
at lambda_method253(Closure , EncodedTextWriter& , BindingContext )
at HandlebarsDotNet.HandlebarsEnvironment.<>c DisplayClass15_0.b0(TextWriter writer, Object context, Object data)
at HandlebarsDotNet.HandlebarsEnvironment.<>cDisplayClass16_0.b0(Object context, Object data)
at Reports.Services.TemplatingService.GenerateReportHtmlAsync(Manifest manifest, JsonDocument reportJson) in /Users/gtolenti/dev/bitbucket/kf-sell-platform/Reports/Services/TemplatingService.cs:line 57
at Reports.Services.ReportService.GenerateReportAsync(JsonDocument reportJson) in /Users/gtolenti/dev/bitbucket/kf-sell-platform/Reports/Services/ReportService.cs:line 93
at Reporting.Controllers.ReportsController.Post(JsonDocument reportJson) in /Users/gtolenti/dev/bitbucket/kf-sell-platform/Reports/Controllers/ReportsController.cs:line 47
at lambda_method7(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.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.gAwaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
After submitting the issue
Please consider contributing to the project by submitting a PR with a fix to the issue. This would help to solve your problem in a shorter time as well as help other users of the project.
In case you do not know where to start - feel free to ask for help in the issue thread.
Building an active community is essential for any project survival as time of maintainers is limited.