Skip to content

Conversation

@Forgind
Copy link
Contributor

@Forgind Forgind commented Dec 29, 2021

I was doing this as part of the TaskHost change. In most cases, it made it easier to understand why tests were failing. Then I went a little further on a couple points, most notably exceptions.

I think the commits are pretty clean. Most are also quite short.


bool success = project.Build(logger);
Assert.True(success); // "Build failed. See test output (Attachments in Azure Pipelines) for details"
project.Build(logger).ShouldBeTrue(); // "Build failed. See test output (Attachments in Azure Pipelines) for details"
Copy link
Member

Choose a reason for hiding this comment

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

While we're here might as well bring back the message:

Suggested change
project.Build(logger).ShouldBeTrue(); // "Build failed. See test output (Attachments in Azure Pipelines) for details"
project.Build(logger).ShouldBeTrue("Build failed. See test output (Attachments in Azure Pipelines) for details");

// first unregister all loggers, since other loggers may receive remaining events in unexpected orderings
// if a fellow logger is throwing in an event handler.
UnregisterAllEventHandlers();

Copy link
Member

Choose a reason for hiding this comment

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

I personally prefer the whitespace here; do you feel strongly about it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only a slight preference, but I do have a stronger preference for either whitespace or no whitespace rather than mixed—the catch (LoggerException) right above this has no space, for instance.


throw;
// Throw the error that caused the TypeInitializationException, likely InvalidOperationException.
throw e.InnerException ?? e;
Copy link
Member

Choose a reason for hiding this comment

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

I think this is actually different, and you should not make this change: throw e; and throw; have different results, because throw e; throws from this stack location, while throw; rethrows the existing exception with its own stack location.

return false;
}
catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
catch (Exception e) when (!ExceptionHandling.IsCriticalException(e)) // Catching Exception, but rethrowing unless it's a well-known exception.
Copy link
Member

Choose a reason for hiding this comment

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

In other cases you dropped the comment. Why not here?

return false;
}
catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
catch (Exception e) when (!ExceptionHandling.IsCriticalException(e)) // Catching Exception, but rethrowing unless it's a well-known exception.
Copy link
Member

Choose a reason for hiding this comment

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

In other cases you dropped the comment. Why not here?

}
}
catch (Exception e)
catch (DirectoryNotFoundException e)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
catch (DirectoryNotFoundException e)
catch (DirectoryNotFoundException e) when (e is DirectoryNotFoundException || e is UnauthorizedAccessException)

instead?

thrownException = ex;
}
catch (Exception ex)
catch (Exception ex) // LoggerException is a polite logger failure. InternalLoggerException is an arbitrary exception. Handle them the same.
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand the "handle them the same" part of this comment. Maybe just delete the comment?

{
_taskLoggingContext.LogWarningFromText(null, warningCode, helpKeyword, new BuildEventFileInfo(_taskLocation), message);
}
catch (InternalErrorException) // BUGBUG, should never catch this
Copy link
Member

Choose a reason for hiding this comment

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

Do you think it's ok to catch this now? Or should we leave the comment that we shouldn't be but are "temporarily"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This didn't really sound like it was a bug to me. Sure, it would be better if we never threw that exception, and we could accomplish something like that by having something to check whether we were cancelled before throwing, but having a catch feels equivalent to me as long as there aren't other ways internal exceptions can come through here. Perhaps it would be slightly better if we had catch (InternalException) when (!_taskLoggingContext.IsValid && weWerentCancelled), but for a try/catch around a single logging statement, that feels like overkill.

taskCleanedUp = _requestTask.Wait(BuildParameters.RequestBuilderShutdownTimeout);
}
catch (AggregateException e)
catch (AggregateException e) when (e.Flatten().InnerExceptions.All(ex => ex is TaskCanceledException || ex is OperationCanceledException))
Copy link
Contributor Author

@Forgind Forgind Jan 10, 2022

Choose a reason for hiding this comment

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

Make a named function here.

}
catch (Exception e)
// If a logger has failed, abort immediately. This is the polite LoggerException.
// InternalLoggerException is an arbitrary logger exception.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Leaving this case of 3+ clauses in because I'd added a comment previously.

}
catch (Exception e /* Wrap all other exceptions in a more meaningful exception*/)
catch (Exception e) // Wrap other exceptions in a more meaningful exception. LoggerException and InternalLoggerException are already meaningful.
when (!(e is LoggerException /* Polite logger Failure*/ || e is InternalLoggerException /* LoggerClass not found*/ || ExceptionHandling.IsCriticalException(e)))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same

// Logger failed politely during construction. In order to preserve
// the stack trace at which the error occurred we wrap the original
// exception instead of throwing.
throw new LoggerException(le.Message, le, le.ErrorCode, le.HelpKeyword);
Copy link
Contributor Author

@Forgind Forgind Jan 10, 2022

Choose a reason for hiding this comment

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

Why not just throw le? (I saw the comment, but I don't see why making a new exception would preserve the stack trace, whereas throwing the exception that had the stack trace wouldn't.)

Copy link
Member

@rokonec rokonec left a comment

Choose a reason for hiding this comment

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

I have carefully reviewed it.
Please consider all my comments as an optional feedback ideas.
Good job.

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.

3 participants