Crashing Sitecore App due to OWIN customization

Challenge

Recently our Sitecore CD App has been crashing ~70+ times per day and it took us roughly 4 weeks to pinpoint an issue. So, thought to share those learnings with you as well. So, you don’t need to invest some time to figure out the root cause and if you are proactive you could avoid such issues in your application as well!

Solution

It took 3.5 weeks for us to collect a Crash dump due to Azure PaaS gotchas and then .5 weeks to fix an issue and deploy it till PROD. I’ve already written a post about 3.5 weeks of struggle to capture a crash dump here: https://www.kiranpatils.com/2021/08/23/a-tale-of-crashing-web-app-and-failing-crash-dump-collection-tools/. If you are curious to know about dump collection challenges, then please read the given post else it’s not mandatory.

High level Application architecture

  • Built on Sitecore 9.3 with SXA
  • Hosted on Azure Web App (PaaS)
  • P2V2 * 4 (Scaled to 4 instances)
  • Multi-site solution using Sitecore hosting 12 websites
  • Serving ~6 M Requests/Day

To begin our troubleshooting we had the following stack trace from Proactive Crash Monitoring (No raw dump file as PCM deletes it)


========================================================
 Dump Analysis for w3wp__app-cd__6f6d__PID__8612__Date__07_20_2021__Time_02_28_56PM__20__ntdll!ZwTerminateProcess_pd0mdwk00000N.dmp             
========================================================
Thread 5272
ExitCode 800703E9
ExitCodeString COR_E_STACKOVERFLOW
Managed Exception = System.StackOverflowException:
CallStack - Managed Exception
========================================================
callstack - Crashing Thread
========================================================
     FaultingExceptionFrame
     HelperMethodFrame
     System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
     Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1+<Invoke>d__5[[System.__Canon, mscorlib]].MoveNext()
     System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
     System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
     System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run()
     System.Threading.Tasks.AwaitTaskContinuation.RunCallback(System.Threading.ContextCallback, System.Object, System.Threading.Tasks.Task ByRef)
     System.Threading.Tasks.Task.FinishContinuations()
     System.Threading.Tasks.Task.Finish(Boolean)
     System.Threading.Tasks.Task`1[[System.Threading.Tasks.VoidTaskResult, mscorlib]].TrySetException(System.Object)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Threading.Tasks.VoidTaskResult, mscorlib]].SetException(System.Exception)
     Microsoft.Owin.Mapping.MapMiddleware+<Invoke>d__3.MoveNext()
     HelperMethodFrame
     System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
     Microsoft.Owin.Mapping.MapMiddleware+<Invoke>d__3.MoveNext()
     System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
     System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
     System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run()
     System.Threading.Tasks.AwaitTaskContinuation.RunCallback(System.Threading.ContextCallback, System.Object, System.Threading.Tasks.Task ByRef)
     System.Threading.Tasks.Task.FinishContinuations()
     System.Threading.Tasks.Task.Finish(Boolean)
     System.Threading.Tasks.Task`1[[System.Threading.Tasks.VoidTaskResult, mscorlib]].TrySetException(System.Object)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Threading.Tasks.VoidTaskResult, mscorlib]].SetException(System.Exception)
     Microsoft.Owin.Mapping.MapMiddleware+<Invoke>d__3.MoveNext()
     HelperMethodFrame
     System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   // Same Stack trace repeats 5 times - removed to save your scroll wheel :-)

As you can see from the above stack trace all assemblies are either System or Microsoft. We shared the above information with Microsoft support and they asked us to reach out to Sitecore. The Sitecore support team asked us to double-check OWIN related customization. Which we had already shared with them and they could also not pinpoint any issues with our OWIN Customization related to Federated Authentication.

As nothing looks suspicious to us and the code has not changed for 6 months we requested Sitecore to help us understand this stack trace more which they started checking with their internal OWIN expert. In the meantime, I also opened GitHub issue here: https://github.com/aspnet/AspNetKatana/issues/424 Where Chris Ross helped us understand the internals of the above stack-trace and what we understood is “Microsoft.Owin.Mapping.MapMiddleware+d__3.MoveNext” invokes OWIN Methods

In the meantime, We were able to capture a crash dump with Raw dump file, and Crash dump analysis helped us pinpoint an exact method:

Simplified method details:

namespace SCBasics.Foundation.Security.Pipelines.OwinInitialize
{
    public class HandleIbeUrl : InitializeProcessor
    {
       

        public override void Process(InitializeArgs args)
        {
            if (!this.Settings.FederatedAuthenticationEnabled())
                return;

            HandleExternalIbeUrl(args);
        }

        protected void HandleExternalIbeUrl(InitializeArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            args.App.Map(string.Concat(Settings.IdentityProcessingPathPrefix().EnsureTrailingSlash(), "externalibeurl"), SessionStateBehavior.Required, app => app.Run(context =>
            {

                // Some custom Code throwing exception when input is wrong - Can Crash your Sitecore App!
                return Task.CompletedTask;

            }));
        }
        
    }
}

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <owin.initialize>
            <processor type="SCBasics.Foundation.Security.Pipelines.OwinInitialize.HandleIbeUrl, SCBasics.Foundation.Security" resolve="true"/>
      </owin.initialize>      
    </pipelines>
  </sitecore>
</configuration>

Once we had steps to reproduce the issue, we tried it on all the environments. Interestingly, We could reproduce this issue on QA and PROD only UAT app was not getting crashed. We compared everything (bin, configs, etc.) but there was no difference. Sitecore was also unable to answer this (It seems something related to “Sitecore.Owin.Pipelines.Initialize.SetGlobalExceptionHandler, Sitecore. Owin”). But as we had a couple of environments (Most Important PROD) we added a fix – And the fix was super simple – Wrapping that code in a try..catch in other words handling exception gracefully! ๐Ÿ™‚

It’s still a mystery to us why App gets crashed due to exceptions at this level. As theoretically it shouldn’t be. But it does in the real world! And that’s what I (And most of the developers) love about our profession! Every challenge is a new puzzle irrespective of your experience! (Experience surely helps!)

Have a healthy and stable Sitecore application!

Reflector tips and tricks every Sitecore Developer should know

In this week whole Sitecore community heard a BIG News that our Sitecore Guru has decided to Bid Farewell to Sitecore community. Whole community was there to wish him luck! And it has a reason. Lot of us (Including me!) started Sitecore coding looking at his blog. In those days. When no Sitecore documentation/blogs were available in the universe except Sir John West’s blog and SDN Forum replies. It is true “Passion is contagious!”

Would like to dedicate this blog post to SirJohn West!

https://community.sitecore.net/general/f/13/p/2524/7208#7208

As Sir John West mentioned here that Reflector is a cool tool to have : http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2011/05/cool-tools-for-sitecore-aspnet-cms-developers.aspx

We know that there are a lot of options available which are free. But somehow I love and prefer to use Reflector. I know it’s paid. But it’s worth. If you would like to convince your boss then give them this link from Joel’s blog : http://www.joelonsoftware.com/articles/fog0000000043.html Tip #9

I have seen that lot of Developers (Senior or Junior) prefer to Search on Google for solution first – Which is good. But if not found then they give up. But so, less folks go ahead and try to see what is happening in Sitecore.Kernel/Any assembly. Because If you ask me what is Best Sitecore documentation then my answer will be “Reflector“. In my 6+ years crafting on Sitecore. Have fixed lot of issue or implemented lot of features using Reflector only! And you know How I started using it? On SDN Forum. John recommended lot of folks to check Reflector. And looking at my seniors who were expert in Sitecore. And they always relied in Reflector to understand any behavior!

So, as life’s secret lies in “The Secret” book ๐Ÿ™‚ Sitecore’s Secret lies in Sitecore’s assemblies and only Reflector can help you read it. So, would like to encourage all Sitecorians to start using Reflector. Earlier days I just used to open each class, method etc. To see what is lying inside? How Sitecore architect something this way? Why they did so? And during this exploration. I learnt Sitecore basics! And once you know Basics – Then it’s easy to become master of any technology “Every expert was once a beginner!”

In this blog, I would like to share some basics. And features I think are less/not used. But very powerful!

  1. Good starter links:
    1. https://www.simple-talk.com/dotnet/.net-tools/first-steps-with-.net-reflector/
    2. https://documentation.red-gate.com/display/REF8/.NET+Reflector+8+documentation
  2. Make sure allย  your required Sitecore assemblies are loaded in reflector
  3. Search string or constant or Exact Match features are good to search any specific error message
  4. If you are searching for Class then make sure Search by Type (CTRL+T) is selected and for Method/Property/Field — Search by Member is selected – Very basic thing!
  5. If you would like to see Where some property/method/field/class is being used then you can use “Analyze” feature. Please refer “Analyze screen”

search-large
Reflector Search screen

Analyze
Analyze screen

Which one is your favorite trick. Which you think we all should know?

Thanks to all of those people who share this small tips and tricks with me!

Happy Coding! ๐Ÿ™‚

Could not run the ‘getMediaStream’ pipeline

Challenge:

After deploying our solution we were checking log files and we found following errors:

2096 02:02:02 ERROR Could not run the ‘getMediaStream’ pipeline for ‘/ImagePath’. Original media data will be used.
Exception: System.OverflowException
Message: Arithmetic operation resulted in an overflow.
Source: Sitecore.Kernel
at Sitecore.ImageLib.ThumbMaker.GetSourceByteAt(Int32 x, Int32 y)
at Sitecore.ImageLib.ThumbMaker.IndexedRezise(Int32 xSize, Int32 ySize, Boolean preserveResolution)
at Sitecore.ImageLib.Resizer.ResizeGif(Bitmap image, Size imageSize, Size frameSize, Color frameColor, Boolean preserveResolution)
at Sitecore.ImageLib.Resizer.Resize(Bitmap bitmap, Size imageSize, Size frameSize, Color frameColor, Boolean preserveResolution, ImageFormat format, InterpolationMode interpolationMode, CompositingMode compositingMode, PixelOffsetMode pixelOffsetMode)
at Sitecore.ImageLib.Resizer.Resize(Bitmap bitmap, ResizeOptions options, ImageFormat format, InterpolationMode interpolationMode)
at Sitecore.Resources.Media.ImageEffectsResize.ResizeImageStream(Stream inputStream, TransformationOptions options, ImageFormat outputFormat)
at Sitecore.Resources.Media.ResizeProcessor.Process(GetMediaStreamPipelineArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Resources.Media.Media.GetStreamFromPipeline(MediaOptions options, Boolean& canBeCached)

6796 02:02:05 ERROR Could not run the ‘getMediaStream’ pipeline for ‘/ImagePath/’. Original media data will be used.
Exception: System.OverflowException
Message: Arithmetic operation resulted in an overflow.
Source: Sitecore.Kernel
at Sitecore.ImageLib.ThumbMaker.GetSourceByteAt(Int32 x, Int32 y)
at Sitecore.ImageLib.ThumbMaker.IndexedRezise(Int32 xSize, Int32 ySize, Boolean preserveResolution)
at Sitecore.ImageLib.Resizer.ResizeGif(Bitmap image, Size imageSize, Size frameSize, Color frameColor, Boolean preserveResolution)
at Sitecore.ImageLib.Resizer.Resize(Bitmap bitmap, Size imageSize, Size frameSize, Color frameColor, Boolean preserveResolution, ImageFormat format, InterpolationMode interpolationMode, CompositingMode compositingMode, PixelOffsetMode pixelOffsetMode)
at Sitecore.ImageLib.Resizer.Resize(Bitmap bitmap, ResizeOptions options, ImageFormat format, InterpolationMode interpolationMode)
at Sitecore.Resources.Media.ImageEffectsResize.ResizeImageStream(Stream inputStream, TransformationOptions options, ImageFormat outputFormat)
at Sitecore.Resources.Media.ResizeProcessor.Process(GetMediaStreamPipelineArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Resources.Media.Media.GetStreamFromPipeline(MediaOptions options, Boolean& canBeCached)

We spent sometime identifying what’s going on. But we couldn’t. Same is the case with you? Then this post is for you. Because later on we figured out with some help

Solution:

As a developer we did quick Google Search and found this thread : https://community.sitecore.net/developers/f/8/t/382

But it didn’t helped. While writing I can see someone replied on 30th October. But our approach is bit different than that. So, thought to write.

Next step was to raise a Sitecore support case.ย  And they have told us that this a BUG, and provided hot-fix as well. Here’s what Sitecore support folks said:

The issue occurs if the <sc:image> tag (for example), which used to render *.gif images, contains the parameters that cause the resize of the image (e.g. “mw”, “mh” for xslt rendering or the “maxWidth”,etc for the sublayout).ย 

To fix issue please try the following:

  • Put attached Sitecore.Support.389864.dll to the Website\bin folder
  • Put attached Sitecore.Support.389864.config to the Website\App_Config\Include folderย 
Please note that this patch was not deeply tested and we recommend you to back up your solution before applying any changes.
In summary, this error will happenย  when you have gif images and while rendering it you try to resize it. Solutions are :
  1. Make it PNG – No deployment required
  2. Apply Sitecore provided hotfix — Deployment and testing required

I won’t attach files here. I would recommend you to get it via Sitecore support. But if you need it. Let me know.

Special thanks to Nikki who worked on this issue

Happy Sitecoring! ๐Ÿ˜‰

The given key was not present in the dictionary error with Glass Mapper

Challenge:

We developed one module, and while testing it on anther machine. We faced following error:

Exception: System.Collections.Generic.KeyNotFoundException
Message: The given key was not present in the dictionary.
Source: mscorlib
ย ย  at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
ย ย  at Glass.Mapper.AbstractService..ctor(String contextName)
ย ย  at Glass.Mapper.Sc.SitecoreService..ctor(String databaseName, String contextName)

Yes, as per the error message. It is something to do with Glass for sure! And yes, we used Glass to fetch data. Sorry you don’t know about Glass? No worries, Will strongly recommend you to start using Glass [The easiest way to map Sitecore data to code.] for all your Sitecore projects — WebForms/MVC. Glass Website : http://glass.lu/en/Mapper/Sc.aspx

Solution:

We did a quick search, and found this thread : https://twitter.com/mp3duck/status/342946214507069440 But, still no luck ๐Ÿ˜ฆ

Then we started our investigation, and found that we missed to deploy : Website\App_Config\Include\Glass.Mapper.Sc.CastleWindsor.config file. Thanks to Nilesh Thakkar!

After doing that, all green!

Happy Glass Mapping! ๐Ÿ™‚

Fix broken Visual Studio Intellisense in Sitecore project

Challenge:

We had a small challenge, Visual Studio Intellisense was not working at all (event for asp: tags as well) for our Sitecore project. This small problem really took lot of hours of ours, and made us scratch our heads. But good news is, we’ve a solution. And great news is — We are going to share with you! So, it saves a lot of your time, which we invested.

So, if you are working on Sitecore Project, and your Visual Studio Intellisense is not working. This post will surely help you to fix it!

Let’s go!

Solution:

As always, we did a quick Google search and we found good articles on this:

From these articles, we tried following things:

  1. Delete .suo file next to your — .sln and Reset VS Settings
  2. Open Command prompt in elevated mode – Run as Admin
  3. CD C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE
  4. Open Visual Studio in safe mode : devenv.exe /SafeMode
  5. Create Empty WebForm Site see Intellisense works here

But neither of this solution worked for us. It worked for you?! You are lucky! Then we decide to delve more in to issue. Then what we did:

We opened Web.Config and commented few assemblies from <assemblies> section.ย  And then we noticed that it started working!

Now, we had an Eureka Moment, There were few assemblies missing in our project folder’s bin directory. And that was causing this issue. If you are new to Project folder term. Then will just brief you. We keep Sitecore files and Project files isolated. Good Reads :

P2S

So, in our case, We had all the assemblies in Sitecore Directory. Which comes with Plain Sitecore. But it was not copied to Project Directory and that was breaking Visual Studio Intellisense.

It fixed your issue? You had/have some different challenge — Feel free to share.

Happy Sitecoring! ๐Ÿ™‚