Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,41 @@ public void EngineShouldHandleExceptionsFromCachePluginViaGraphBuild(ErrorLocati
}
}

[Fact]
public async Task CriticalExceptionFromGraphBuildCompletesSubmission()
{
const string exceptionMessage = "Critical exception from graph build";

var project = _env.CreateFile(
"1.proj",
"""
<Project>
<Target Name="Build" />
</Project>
""");
var graph = new ProjectGraph(project.Path);
var cache = new DelegatingMockCache(
(_, _, _) => throw new InternalErrorException(exceptionMessage));
var buildParameters = new BuildParameters
{
ProjectCacheDescriptor = ProjectCacheDescriptor.FromInstance(cache),
ShutdownInProcNodeOnBuildFinish = true
};
var requestData = new GraphBuildRequestData(graph, ["Build"]);

Task<InternalErrorException> buildTask = Task.Run(
() =>
{
using var buildManager = new BuildManager();
return Should.Throw<InternalErrorException>(() => buildManager.Build(buildParameters, requestData));
});

Task completedTask = await Task.WhenAny(buildTask, Task.Delay(TimeSpan.FromSeconds(10)));

completedTask.ShouldBeSameAs(buildTask, "Graph builds should complete after a critical exception.");
(await buildTask).Message.ShouldContain(exceptionMessage);
}
Comment thread
AlesProkop marked this conversation as resolved.

[Fact]
public void EndBuildShouldGetCalledOnceWhenItThrowsExceptionsFromGraphBuilds()
{
Expand Down
20 changes: 16 additions & 4 deletions src/Build/BackEnd/BuildManager/BuildManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1772,9 +1772,9 @@ private void ExecuteSubmission(GraphBuildSubmission submission)
{
ExecuteGraphBuildScheduler(submission);
}
catch (Exception ex) when (!ExceptionHandling.IsCriticalException(ex))
catch (Exception ex)
{
HandleSubmissionException(submission, ex);
HandleGraphSubmissionException(submission, ex);
}
},
_executionCancellationTokenSource!.Token,
Expand All @@ -1783,13 +1783,25 @@ private void ExecuteSubmission(GraphBuildSubmission submission)
}
}
// The handling of submission exception needs to be done outside of the lock
catch (Exception ex) when (!ExceptionHandling.IsCriticalException(ex))
catch (Exception ex)
{
HandleSubmissionException(submission, ex);
HandleGraphSubmissionException(submission, ex);
throw;
}
}

private void HandleGraphSubmissionException(GraphBuildSubmission submission, Exception ex)
{
if (ExceptionHandling.IsCriticalException(ex))
{
OnThreadException(ex);
}
else
{
HandleSubmissionException(submission, ex);
}
}

/// <summary>
/// Creates the traversal and metaproject instances necessary to represent the solution and populates new configurations with them.
/// </summary>
Expand Down
Loading