Skip to content

Conversation

benvillalobos
Copy link
Member

@benvillalobos benvillalobos commented Oct 5, 2021

Fixes #6275

Context

When a task logs an error, its logging helper properly realizes that it logged an error. The overall build, however, converts that error into a warning. This leads to very confusing scenarios where a task can return "I logged an error" that the TaskBuilder recognizes, but doesn't see that an error was logged because it was turned into a warning.

Changes Made

When a taskhost logs an error, even if it was converted into a warning, it understands that an error was logged but does not fail the build.

Testing

Notes

@benvillalobos benvillalobos marked this pull request as ready for review October 6, 2021 17:55
IBuildEngine be = host.TaskInstance.BuildEngine;
if (taskReturned && !taskResult && !taskLoggingContext.HasLoggedErrors && (be is TaskHost th ? th.BuildRequestsSucceeded : false) && (be is IBuildEngine7 be7 ? !be7.AllowFailureWithoutError : true))
{
if (_continueOnError == ContinueOnError.WarnAndContinue)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not log a warning here? The idea was to convert the error into a warning, not to ignore it completely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message is redundant in the case that the error was turned into the warning. Though it's worth noting that this hides a real issue where a task sets WarnAndContinue but truly doesn't log an error and returns false. Need to think about this some more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice, this says that if ContinueOnError is set, we don't log MSB4181, period, no matter what they did. HasLoggedErrors can (and should) be set if they tried to log an error but converted it into a warning; a lot of tasks return !HasLoggedErrors anyway. I don't feel at all bad about logging two warnings for a poorly-constructed task, but it is bad to not log anything when a task returns false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this = 💡

Is the fix here really just...making sure RemoveDir returns !HasLoggedErrors? It straight up returns whether it actually deleted the file 🤦‍♂️

In the implementation of RemoveDir, it returns true or false based on whether or not it actually deleted the directory. However we want our typical task to return true as long as it successfully did something, otherwise it logs an error and reports whether it did. The issue with RemoveDir is it doesn't follow that structure. I think we need to change the logic of how RemoveDir works and add an Output parameter similar to copy's "DidActuallyWriteAFile".

RemoveDir for reference: https://github.com/dotnet/msbuild/blob/main/src/Tasks/RemoveDir.cs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably a good idea to change RemoveDir to use the !Log.HasLoggedErrors pattern that we recommend. But I'm not sure it's wrong to just never log this malformed-task error in the presence of ContinueOnErrors. It is definitely wrong to report it when the task tried to log an error but was prevented.

I agree that the other change in this PR is the critical one. IIRC when we were talking about this I wanted to do this as well but I can't remember exactly why.

Let's do this: please add a new test task (or find a configuration that does this): ReturnFailureAfterLoggingErrorTask, and add a test for it (doesn't log the supplemental error when logging an error that gets converted). That should fail against main and pass with the TaskHost change alone. And maybe that's sufficient?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't already have it, I think it would also be nice to have a separate task that does not attempt to log an error but returns false, then verify that with ContinueOnError.WarnAndContinue, MSB4181 is still displayed, just as a warning.

_taskLoggingContext.LoggingService.LogBuildEvent(e);
_taskLoggingContext.HasLoggedErrors = true;
}
_taskLoggingContext.HasLoggedErrors = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this fail the build? If someone want to "WarnAndContinue," we probably shouldn't, but this does seem like the change that would prevent 4181.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: spacing.

@Forgind Forgind changed the title Propertly report HasLoggedErrors when converting errors into warnings Properly report HasLoggedErrors when converting errors into warnings Oct 11, 2021
Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC there was a request for a new test scenario, right?

_taskLoggingContext.LoggingService.LogBuildEvent(e);
_taskLoggingContext.HasLoggedErrors = true;
}
_taskLoggingContext.HasLoggedErrors = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: spacing.

@benvillalobos
Copy link
Member Author

@rainersigwald Fixed. Added the deleted test back and a new test to ensure:

  1. Task returns false and logs error does NOT also log msb4181
  2. Task returns false and logs nothing DOES log msb4181
    both under the ContinueOnError case.

@rainersigwald rainersigwald added this to the MSBuild 17.1 milestone Oct 25, 2021
@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Oct 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RemoveDir task should log an error when failing

4 participants