Welcome to AspAdvice Sign in | Join | Help

Fixed: CCNET + MSBUILD Logger Error

Ran into a snag this weekend with my build server - it started throwing errors related to the path to a folder, like this:

.MSBUILD : error MSB4015: The build was aborted because the "MsBuildToCCNetLogger" logger failed unexpectedly during shutdown. System.ArgumentException: The path is not of a legal form. at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.GetDirectoryName(String path) at Rodemeyer.MsBuildToCCNet.MsBuildToCCNetLogger.WriteErrorsOrWarnings(XmlWriter w, String type, IEnumerable list) at Rodemeyer.MsBuildToCCNet.MsBuildToCCNetLogger.WriteProject(XmlWriter w, Project p) at Rodemeyer.MsBuildToCCNet.MsBuildToCCNetLogger.WriteLog(XmlWriter w) at Rodemeyer.MsBuildToCCNet.MsBuildToCCNetLogger.Shutdown() at Microsoft.Build.BuildEngine.Engine.UnregisterAllLoggers()

 

I hadn't changed anything in my server configuration, nor had I moved around any files in my project.  The last thing I'd done was make some updates to my Database Project (VSTS Database Professional SKU), which had resulted in some errors and warnings (which I was happy to ignore since they were without merit).

My first thought was that perhaps I'd run into an existing bug, so I upgraded from CruiseControl .NET 1.1 to 1.3, the latest build.  That didn't work.

The logger I'm using is a separate open source DLL from Christian Rodemeyer, Rodemeyer.MsBuildToCCnet.dll.  Mine was from Jan 2007 and his latest on his website was from March 2007, so I upgraded.  That didn't work, either.

Happily, I had a decent stack trace and the source to MsBuildToCCnet is available (and complete with a .sln file and everything - nice!) so I snagged it and quickly found my problem in Logger.cs [line 157]:

private void WriteErrorsOrWarnings(XmlWriter w, string type, System.Collections.IEnumerable list)
{
    foreach (ErrorOrWarningBase ew in list)
    {
        w.WriteStartElement(type);
        w.WriteAttributeString("code", ew.Code);
        w.WriteAttributeString("message", ew.Text);
        w.WriteAttributeString("dir", Path.GetDirectoryName(ew.File));
        w.WriteAttributeString("name", Path.GetFileName(ew.File));
        w.WriteAttributeString("pos", "(" + XmlConvert.ToString(ew.Line) + ", " + XmlConvert.ToString(ew.Column) + ")");
        w.WriteEndElement();
    }
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

My error was occurring on Path.GetDirectoryName() so I logged the value of ew.File (a string property) and found that it was empty.  Probably the database error or warning I was getting was not associated with a file, and that was the root of my problem.

I updated the method as follows - feel free to cut-and-paste.  Hopefully Christian will include this in a future revision:

private void WriteErrorsOrWarnings(XmlWriter w, string type, System.Collections.IEnumerable list)
{
    foreach (ErrorOrWarningBase ew in list)
    {
        w.WriteStartElement(type);
        w.WriteAttributeString("code", ew.Code);
        w.WriteAttributeString("message", ew.Text);
        if (!String.IsNullOrEmpty(ew.File)) // Added 22 July 2007 by Steven Smith
        {
            w.WriteAttributeString("dir", Path.GetDirectoryName(ew.File));
            w.WriteAttributeString("name", Path.GetFileName(ew.File));
        }
        w.WriteAttributeString("pos", "(" + XmlConvert.ToString(ew.Line) + ", " + XmlConvert.ToString(ew.Column) + ")");
        w.WriteEndElement();
    }
}

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Hopefully if you encounter the same issue, this post will help you resolve it.  Not writing out the dir and name attributes appeared to have no ill effect on the overall logger behavior, and my build is green again!  w00t!
Published Sunday, July 22, 2007 11:54 AM by ssmith
Filed under: , , , ,

Comments

New Comments to this post are disabled