Confusing behavior of MSBuild logger on raising LogError event

 

Today I found that raising the error message was not enough for the msbuild to stop and invoke the targets specified by OnError tag. For example in the given sample -

 

Custom task:- MSBuildTask.dll

 

namespace MSBuildTask

{

    public class MSBuildTask : Task

    {

        public override bool Execute()

        {

            string msg = " message before raising error event";

            base.BuildEngine.LogMessageEvent(

new BuildMessageEventArgs( msg, String.Empty,

String.Empty, MessageImportance.Normal));

            msg = " error message ";

            base.BuildEngine.LogErrorEvent(

        new BuildErrorEventArgs(String.Empty, String.Empty,

String.Empty, 0, 0, 0, 0, msg, String.Empty,

String.Empty));

            msg = "error message after error event";

            base.BuildEngine.LogMessageEvent(

               new BuildMessageEventArgs(msg, String.Empty,

                  String.Empty, MessageImportance.Normal));

            return true;

        }

    }

}

Project file

 

<Project

xmlns="https://schemas.microsoft.com/developer/msbuild/2003">

<UsingTask TaskName="MSBuildTask.MSBuildTask"

      AssemblyFile="MSBuildTask.dll" />  

 

  <Target Name="TestTarget">

       <Message Text=" Before starting the custom task "/>

       <MSBuildTask ContinueOnError="true"/>

       <Message Text=" After running the custom task "/>

       <OnError ExecuteTargets="TargetExecOnError;" />

  </Target>

  <Target Name="TargetExecOnError">

     <Message Text=" Task to be executed on error "/>

  </Target>

</Project>

 

Irrespective of whether you set ContinueOnError to true or false, you will never be able to execute targets specified by OnError tag. Moreover you will get the message “error message after error event” on console. This is contrary to believe I had that raising error event in MSBuild is equivalent to raising an exception in code and the rest of task code/following targets will not execute. This is not true.

 

Findings

  1. The targets specified by OnError tag will be executed only when task returns false. If you are raising the error event in your custom msbuild task then it is your responsibility to return false status and make task fails.
  2. Raising the error event is not equivalent to raising the exception. As shown in the example above, you will always get the message “After running the custom task”