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?
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)...
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.
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);
}
}
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!
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.
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.
ContentFinder error
We have got an umbraco 7.3.3 site. Part of the code we have a content finder it looks like this:
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
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
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
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 withinTryGetContent
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 thatrequest.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
.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:
Regards
Ismail
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!
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
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
is working on a reply...