Fixing NRE when CacheTagHelper throws and exception (#5989)

Fixes #5988
This commit is contained in:
twirpx 2017-03-28 00:45:22 +05:00 committed by Sébastien Ros
parent 575fe68b2b
commit 58317b18ce
2 changed files with 97 additions and 1 deletions

View File

@ -104,10 +104,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
// such that the tokens are inherited.
result = ProcessContentAsync(output);
content = await result;
entry.SetOptions(options);
entry.Value = result;
content = await result;
}
}
catch

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Encodings.Web;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
@ -647,6 +648,100 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Assert.Equal(2, calls);
}
[Fact]
public async Task ProcessAsync_ExceptionInProcessing_DoNotThrowInSubsequentRequests()
{
// Arrange
var id = "unique-id";
var childContent = "some-content";
var cache = new MemoryCache(new MemoryCacheOptions());
var counter = 0;
Task<TagHelperContent> GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
{
counter++;
if (counter < 3)
{
// throw on first two calls
throw new Exception();
}
else
{
// produce content on third call
var tagHelperContent = new DefaultTagHelperContent();
tagHelperContent.SetHtmlContent(childContent);
return Task.FromResult<TagHelperContent>(tagHelperContent);
}
}
var tagHelperContext1 = GetTagHelperContext(id);
var tagHelperContext2 = GetTagHelperContext(id);
var tagHelperContext3 = GetTagHelperContext(id);
var tagHelperContext4 = GetTagHelperContext(id);
var tagHelperOutput1 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
var tagHelperOutput2 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
var tagHelperOutput3 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
var tagHelperOutput4 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
{
ViewContext = GetViewContext(),
Enabled = true,
ExpiresAfter = TimeSpan.FromHours(1.0)
};
// Act - 1
await Assert.ThrowsAsync<Exception>(() => cacheTagHelper.ProcessAsync(tagHelperContext1, tagHelperOutput1));
// Assert - 1
Assert.Equal(1, counter);
Assert.Empty(tagHelperOutput1.PreContent.GetContent());
Assert.Empty(tagHelperOutput1.PostContent.GetContent());
Assert.False(tagHelperOutput1.IsContentModified);
Assert.Empty(tagHelperOutput1.Content.GetContent());
// Act - 2
await Assert.ThrowsAsync<Exception>(() => cacheTagHelper.ProcessAsync(tagHelperContext2, tagHelperOutput2));
// Assert - 2
Assert.Equal(2, counter);
Assert.Empty(tagHelperOutput2.PreContent.GetContent());
Assert.Empty(tagHelperOutput2.PostContent.GetContent());
Assert.False(tagHelperOutput2.IsContentModified);
Assert.Empty(tagHelperOutput2.Content.GetContent());
// Act - 3
await cacheTagHelper.ProcessAsync(tagHelperContext3, tagHelperOutput3);
// Assert - 3
Assert.Equal(3, counter);
Assert.Empty(tagHelperOutput3.PreContent.GetContent());
Assert.Empty(tagHelperOutput3.PostContent.GetContent());
Assert.True(tagHelperOutput3.IsContentModified);
Assert.Equal(childContent, tagHelperOutput3.Content.GetContent());
// Act - 4
await cacheTagHelper.ProcessAsync(tagHelperContext4, tagHelperOutput4);
// Assert - 4
Assert.Equal(3, counter);
Assert.Empty(tagHelperOutput4.PreContent.GetContent());
Assert.Empty(tagHelperOutput4.PostContent.GetContent());
Assert.True(tagHelperOutput4.IsContentModified);
Assert.Equal(childContent, tagHelperOutput4.Content.GetContent());
}
private static ViewContext GetViewContext()
{