Session Submit fails when Response.Redirect() is called after Session.Abandon()


Description

An error can occur while saving a session when:

When the error occurs, the following messages are written to the log:

ERROR PostSessionEndPipeline failed.
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Source: Sitecore.Analytics
   at Sitecore.Analytics.Pipelines.CommitSession.SubmitSession.Process(CommitSessionPipelineArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
   at Sitecore.Analytics.Pipelines.CommitSession.CommitSessionPipeline.Run(CommitSessionPipelineArgs args)
   at Sitecore.Analytics.Pipelines.PostSessionEnd.CommitSession.Process(PostSessionEndArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
   at Sitecore.Pipelines.EndSession.PostSessionEndPipeline.Run(PostSessionEndArgs args)
   at Sitecore.Web.Application.RaiseSessionEndEvent(HttpApplication context)
WARN  Session Submit has failed.
Exception: System.InvalidOperationException
Message: args.Session.Contact is not set.
Source: Sitecore.Analytics
   at Sitecore.Analytics.Pipelines.SubmitSessionContext.RenumberInteractions.Process(SubmitSessionContextArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
   at Sitecore.Analytics.Pipelines.SubmitSessionContext.SubmitSessionContextPipeline.Run(SubmitSessionContextArgs args)
   at Sitecore.Analytics.Data.HttpSessionContextManager.Submit(Session session)
   at Sitecore.Analytics.Pipelines.CommitSession.SubmitSession.Process(CommitSessionPipelineArgs args)

Explanation

It is a Sitecore Analytics requirement that all ASP.NET request lifecycle events are executed.

However, according to Microsoft documentation:

"If you specify true for the endResponse parameter, this method calls the End method for the original request, which throws ThreadAbortException method for the original request, which throws an exception when it completes. This exception has a detrimental effect on Web application performance, which is why passing false for the endResponse parameter is recommended."

Consequently, when Response.Redirect() is called (calling Redirect is equivalent to calling Redirect with the second parameter set to true), the request is aborted. In this case, required cleanup logic is not performed and the mentioned exceptions are thrown.

Solution

To solve the issue, change the code to:

HttpContext.Current.Session.Abandon();
Response.Redirect(Request.Url.Scheme + "://" + Request.Url.Host, false);