From 33f6c93c49d07bdaa250d17d58cb870968392f38 Mon Sep 17 00:00:00 2001 From: Rex Morgan Date: Fri, 19 Jun 2026 20:55:54 -0400 Subject: [PATCH] fix: clearer error when partial registered on wrong Handlebars instance (issue #545) Improved the HandlebarsRuntimeException message thrown when a partial cannot be resolved to include a diagnostic hint about the common pitfall of registering a partial on the static Handlebars class but compiling/rendering on a separate IHandlebars instance. Also added quotes around the partial name for readability. Added two regression tests for issue #545 covering both the correct same-instance pattern and the helpful error when mixing static and instance APIs. Co-Authored-By: Claude Sonnet 4.6 --- source/Handlebars.Test/IssueTests.cs | 31 +++++++++++++++++++ source/Handlebars.Test/PartialTests.cs | 4 +-- .../Translation/Expression/PartialBinder.cs | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/source/Handlebars.Test/IssueTests.cs b/source/Handlebars.Test/IssueTests.cs index 31136117..14c8f8c0 100644 --- a/source/Handlebars.Test/IssueTests.cs +++ b/source/Handlebars.Test/IssueTests.cs @@ -733,5 +733,36 @@ public void UnrecognisedExpressionThrowsOutOfMemoryException() Assert.Throws(()=> Handlebars.Compile(source)); } + + // Issue: https://github.com/Handlebars-Net/Handlebars.Net/issues/545 + // Partial registered on an instance should be found during render on that same instance + [Fact] + public void Issue545_PartialRegisteredOnInstanceIsFoundDuringRender() + { + // This is the CORRECT pattern — register and compile on same instance + var handlebars = Handlebars.Create(); + handlebars.RegisterTemplate("content", "

{{message}}

"); + var template = handlebars.Compile("
{{> content}}
"); + var result = template(new { message = "Hello" }); + Assert.Equal("

Hello

", result); + } + + // Issue: https://github.com/Handlebars-Net/Handlebars.Net/issues/545 + // Mixing static registration with instance compilation should give a helpful error message + [Fact] + public void Issue545_MixingStaticAndInstanceGivesHelpfulError() + { + // Register on static instance + Handlebars.RegisterTemplate("staticContent545", "

static

"); + + // Compile on a different instance — should give a useful error + var handlebars = Handlebars.Create(); + var template = handlebars.Compile("
{{> staticContent545}}
"); + var ex = Assert.Throws(() => template(new { })); + // The error should mention the partial name clearly + Assert.Contains("staticContent545", ex.Message); + // The error should hint that the user may have registered on the wrong instance + Assert.Contains("static Handlebars class", ex.Message); + } } } \ No newline at end of file diff --git a/source/Handlebars.Test/PartialTests.cs b/source/Handlebars.Test/PartialTests.cs index bbd8e896..9fb2d410 100644 --- a/source/Handlebars.Test/PartialTests.cs +++ b/source/Handlebars.Test/PartialTests.cs @@ -680,7 +680,7 @@ public void RecursionUnboundedBlockPartialWithSpecialNamedPartial() ex = Assert.IsType(ex.InnerException); Assert.Equal("Runtime error while rendering partial 'myPartial', see inner exception for more information", ex.Message); ex = Assert.IsType(ex.InnerException); - Assert.Equal("Referenced partial name @partial-block could not be resolved", ex.Message); + Assert.StartsWith("Referenced partial name '@partial-block' could not be resolved", ex.Message); Assert.Null(ex.InnerException); } @@ -694,7 +694,7 @@ public void TemplateWithSpecialNamedPartial() var data = new {}; var ex = Assert.Throws(() => template(data)); - Assert.Equal("Referenced partial name @partial-block could not be resolved", ex.Message); + Assert.StartsWith("Referenced partial name '@partial-block' could not be resolved", ex.Message); } public class TestMissingPartialTemplateHandler : IMissingPartialTemplateHandler diff --git a/source/Handlebars/Compiler/Translation/Expression/PartialBinder.cs b/source/Handlebars/Compiler/Translation/Expression/PartialBinder.cs index 57467832..1677c211 100644 --- a/source/Handlebars/Compiler/Translation/Expression/PartialBinder.cs +++ b/source/Handlebars/Compiler/Translation/Expression/PartialBinder.cs @@ -98,7 +98,7 @@ private static void InvokePartialWithFallback( if (context.PartialBlockTemplate == null) { if (configuration.MissingPartialTemplateHandler == null) - throw new HandlebarsRuntimeException($"Referenced partial name {partialName} could not be resolved"); + throw new HandlebarsRuntimeException($"Referenced partial name '{partialName}' could not be resolved. If you registered the partial on the static Handlebars class, make sure to also compile and render using the same static class (or register the partial on the IHandlebars instance you are using to compile)."); configuration.MissingPartialTemplateHandler.Handle(configuration, partialName, writer); return;