1
Vote

Null exception can occur if TeamCity is in cleanup or no build exists

description

TeamCity can be configured to run a cleanup operation. When this happens, remote access is suspended and returns "Clean up"

If BuildScreen polls at this time, it throws a null reference exception in GetLastBuildIdByTypeId.
A null exception can also be thrown if a project exists but has never had any builds against it.
    private string GetLastBuildIdByTypeId(string typeId)
    {
        Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "{0}buildTypes/id:{1}/builds/?count=1", BasicUri(), typeId));

        XDocument xDocument = LoadXmlDocument(uri);
        XAttribute buildIdAttribute = (from xml in xDocument.Elements("builds").Elements("build").Attributes("id")
                                        select xml).FirstOrDefault();

            return buildIdAttribute.Value; // BuildIdAttribute is null at this point and throws exception
    }
Potential workaround is to check for object value and return "-1", and then check for this when getting the list of builds
    private string GetLastBuildIdByTypeId(string typeId)
    {
        Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "{0}buildTypes/id:{1}/builds/?count=1", BasicUri(), typeId));

        XDocument xDocument = LoadXmlDocument(uri);
        XAttribute buildIdAttribute = (from xml in xDocument.Elements("builds").Elements("build").Attributes("id")
                                        select xml).FirstOrDefault();
        if (buildIdAttribute != null)
            return buildIdAttribute.Value;
        else
            return "-1"; // Ooops ... no builds or offline?
    }
Important to then catch this when building a list of "builds"
    public ReadOnlyCollection<Build> Builds()
    {
        IList<Build> builds = new List<Build>();

        foreach (string typeId in GetAllTypeIds())
        {
            string LastBuildId = GetLastBuildIdByTypeId(typeId);
            if (LastBuildId != "-1") // Don't add build if an error occurred or no builds exists
            {
                builds.Add(GetBuildByBuildId(LastBuildId));
            }
        }

        return new ReadOnlyCollection<Build>(builds);
    }

comments

galaktor wrote Jan 27, 2012 at 7:26 AM

FYI I fixed this in my fork.