Developer forum

Forum » CMS - Standard features » Tons of ThreadAbort exceptions

Tons of ThreadAbort exceptions

Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

We're seeing many ThreadAbortExceptions being logged under System\Log\Templates\Errors\Year\Month, like this:

2018-10-09 15:31:11.1269|ERROR|Templates|Error in razor template|System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at System.Web.HttpResponse.AbortCurrentThread()
   at System.Web.HttpResponse.Redirect(String url, Boolean endResponse, Boolean permanent)
   at CompiledRazorTemplates.Dynamic.cfdfadbeffafdc.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at System.Web.HttpResponse.AbortCurrentThread()
   at System.Web.HttpResponse.Redirect(String url, Boolean endResponse, Boolean permanent)
   at CompiledRazorTemplates.Dynamic.cfdfadbeffafdc.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
2018-10-09 15:31:11.1269|ERROR|Templates|Error in razor template|System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at System.Web.HttpResponse.AbortCurrentThread()
   at System.Web.HttpResponse.Redirect(String url, Boolean endResponse, Boolean permanent)
   at CompiledRazorTemplates.Dynamic.bcaabceeda.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at System.Web.HttpResponse.AbortCurrentThread()
   at System.Web.HttpResponse.Redirect(String url, Boolean endResponse, Boolean permanent)
   at CompiledRazorTemplates.Dynamic.bcaabceeda.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

These usually come from redirects, either from our own code or from standard code. Is there any way to suppress these? Maybe add an NLog filter to skip them? We're eight days into October and I already have 20K of them, making it impossible to open the folder in the backend and unnecessarily filling up the server.

Thanks!

 


Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply
This post has been marked as an answer

Hi Imar,

It seems that this is only an issue when you make redirects directly in your razor templates.
Usually we make redirect in modules - not templates - so we haven't seen this problem before.
As a workaround you can move your redirect into a NotificationSubscriber or make the redirect in JavaScript.

We should of course not fill the logs with entries related to ThreadAbortException. I have added it to our backlog (TFS #56610)

/Morten

Votes for this answer: 1
 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Morten,

 

I applied the javascipt workaround in a test website and I got a 2 for 1:

  • No more logs for them - the benefit Imar explained above
  • Faster UX (despite the page taking longer to render for the js to be triggered)
    This seemed to be a result of the time NLog takes to process the exception and write it to a file.

 

Assuming this is valid, it prooves why some of our requests are taking longer than expected. With this fix, we will not even have to wait for the entire page to render, get downloaded, processed by the browser before being redirected (creating a NotificationSubscriber for all our scenarios is not a nice solution either).

 

Since this is widespread in a lot of our customers and we would like to apply it sooner rather than waiting for 9.6, it is doable to get this TFS item into a 9.5 hotfix? That would give us a quick performance increase in some of our customers.

 

Best Regards,

Nuno Aguiar

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Hi Morten,

I looked at the implementation of 56610 in TFS. It now indeed no longer logs, but it looks like it will now always throw an error. Previously, it was throwing or not depending on ThrowExceptionOnOutputError, right? Would this cause additional issues with redirects?

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

Hi Imar,

What kind of issues are you concerned about?

I don't think it really matters if we rethrow the ThreadAbortException or not...

"ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block."

You can verify this with the following code:

try
{
    try
    {
        // This redirect will cause a ThreadAbortException to be thrown
        System.Web.HttpContext.Current.Response.Redirect("http://www.google.com");
    }
    catch
    {
        // catch all exceptions
    }
}
catch (System.Exception ex)
{
    // We still get a ThreadAbortException here
}
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Not sure as I don't know what else Dynamicweb is doing when these exceptions happen. Your example makes perfect sense (we've been having a long discussion about this internally for a while) and I agree that it shouldn't make a difference. Just wanted to check while it's still fresh on our minds and not be caught by surprise when this is released in 9.6 ;-)

Imar

 

You must be logged in to post in the forum