Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Apr 13, 2016 @ 16:34
    Ismail Mayat
    0

    ContentFinder error

    We have got an umbraco 7.3.3 site. Part of the code we have a content finder it looks like this:

    public class StationsContentFinder : ContentFinderByNiceUrl
    {
        const string StationsXPath = "//Stations[contains(@path,'{0}')]";
    
        public override bool TryFindContent(PublishedContentRequest request)
        {
            if (base.TryFindContent(request)) return true;
    
            var rootId = request.UmbracoDomain.RootContentId; // multilingual site we need root 
    
            var urlChunks = request.Uri.AbsolutePath.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
    
            if (IsSingleLetter(urlChunks))
            {
                request.RoutingContext.UmbracoContext.HttpContext.Items.Add("StationLetter", urlChunks.Last().ToUpper());
    
                string stationXPath = string.Format(StationsXPath, rootId);
    
                var stationsNode =  request.RoutingContext.UmbracoContext.ContentCache.GetByXPath(stationXPath).FirstOrDefault();
    
                if (stationsNode == null) { return false; }
    
                request.PublishedContent = stationsNode;
    
                //the stations hijack will take over and test for the letter and get the list of stations
    
                return true;
            }
            return false;
        }
    
        private static bool IsSingleLetter(List<string> urlChunks)
        {
            return urlChunks.Last().Length == 1 && Char.IsLetter(urlChunks.Last().ToCharArray()[0]);
        }
    }
    

    All works fine on our servers. We gave it to client to deploy and it works fine on their dev environment.

    The dev consists of front end server and back office server. Site works fine.

    The live consists of 2 load balanced servers with NGINX load balancer

    When they deploy to live it works for a while then site goes down. In the log file we get

     Object reference not set to an instance of an object.   at Application.Web.ContentFinders.StationsContentFinder.TryFindContent(PublishedContentRequest request) line 36
    

    Line 36 is just return false;

    Currently client is having to recycle app pool every hour. This fixes error then re occurs after a while.

    One other thing to note the umbraco instances are hosted in a virtual directory.

    Has anyone seen this before or any ideas on what's going on?

    Regards

    Ismail

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Apr 13, 2016 @ 16:47
    Chriztian Steinmeier
    1

    It doesn't look like this could be causing the problem, but I do see one tiny issue: The XPath you're using could very well get you some false positives (if the root id is 1234 and a node in another node's path has the id 21234)...

    A safer XPath would be something like:

    //Station[ancestor::*[@id={0}]]

    2 cents... /Chriztian

  • Stephen 767 posts 2273 karma points c-trib
    Apr 14, 2016 @ 09:37
    Stephen
    101

    The return false; statement cannot trigger a nullref exception, so most probably some confusion between the source code and the actual Dll means that the line number is wrong. The exception is thrown within TryGetContent and that is all we know.

    What can be null in there?

    In rootId = request.UmbracoDomain.RootContentId, UmbracoDomain could be null on some requests. It would be safer to check that request.HasDomain first, and (probably) ignore requests that don't have a domain.

    Everything that is request.Uri, request.RoutingContext.* should not be null since they are supplied by Umbraco. I don't see what else could be null.

    So... my bet is on UmbracoDomain.

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Apr 14, 2016 @ 11:10
    Ismail Mayat
    0

    Stephan,

    Cool will try this I have updated the content finder also added logging see if i can determine anything from the logs. Although on my dev it all works I dont see anything in umbraco logs which is a bit weird my class now looks like:

    public class StationsContentFinder : ContentFinderByNiceUrl
    {
        const string StationsXPath = "//Stations[contains(@path,'{0}')]";
    
        public override bool TryFindContent(PublishedContentRequest request)
        {
            if (base.TryFindContent(request)) return true;
    
            try
            {
                if (request.HasDomain)
                {
                    var rootId = request.UmbracoDomain.RootContentId; // multilingual site we need root 
    
                    Log("working with root id " + rootId);
    
                    Log("using base uri " + request.Uri.AbsolutePath);
    
                    var urlChunks =
                        request.Uri.AbsolutePath.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                            .ToList();
    
                    if (IsSingleLetter(urlChunks))
                    {
                        Log("got letter " + urlChunks.Last().ToUpper());
    
                        request.RoutingContext.UmbracoContext.HttpContext.Items.Add("StationLetter",
                            urlChunks.Last().ToUpper());
    
                        string stationXPath = string.Format(StationsXPath, rootId);
    
                        var stationsNode =
                            request.RoutingContext.UmbracoContext.ContentCache.GetByXPath(stationXPath).FirstOrDefault();
    
                        if (stationsNode == null)
                        {
                            return false;
                        }
    
                        Log("found stations node " + stationsNode.Name + " id " + stationsNode);
    
                        request.PublishedContent = stationsNode;
    
                        //the stations hijack will take over and test for the letter and get the list of stations
    
                        return true;
                    }
                }
                else
                {
                    Log("no domain");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error<Exception>("Error with station content finder",ex);
            }
            return false;
        }
    
        private static bool IsSingleLetter(List<string> urlChunks)
        {
            return urlChunks.Last().Length == 1 && Char.IsLetter(urlChunks.Last().ToCharArray()[0]);
        }
    
        private void Log(string message)
        {
            LogHelper.Debug(typeof(StationsContentFinder), message);
        }
    }
    

    Regards

    Ismail

  • Stephen 767 posts 2273 karma points c-trib
    Apr 14, 2016 @ 11:13
    Stephen
    0

    Looks good. Point is, in dev you are requesting "known" urls that do match to your domains, whereas in production you are potentially getting "rogue" urls that maybe don't match any domain. Let me know if it works!

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Apr 14, 2016 @ 11:22
    Ismail Mayat
    0

    Stephan,

    Cool will get this deployed and test. Also figured out my logging error i was doing debug but log4net was set to info have set it to all i can now see logs. So hopefully if it goes down again on live we may be able to log urls then see whats going on.

    Regards

    Ismail

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Apr 15, 2016 @ 09:18
    Ismail Mayat
    0

    Stephan,

    We deployed the update yesterday and so far it seems to be stable. Currently being monitored the client has turned off hourly app pool recycle so fingers crossed.

    Thanks for your help.

    Regards

    Ismail

Please Sign in or register to post replies

Write your reply to:

Draft