Skip to content

Commit

Permalink
Make exception summarizer work with derived exception types
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Taillefer committed Sep 7, 2023
1 parent c51001c commit 8565028
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,11 @@

namespace Microsoft.Extensions.Diagnostics.ExceptionSummarization;

/// <summary>
/// Looks through all the registered summary providers, returns a summary if possible.
/// </summary>
internal sealed class ExceptionSummarizer : IExceptionSummarizer
{
private const string DefaultDescription = "Unknown";
private readonly FrozenDictionary<Type, IExceptionSummaryProvider> _exceptionTypesToProviders;

/// <summary>
/// Initializes a new instance of the <see cref="ExceptionSummarizer"/> class.
/// </summary>
/// <param name="providers">All registered exception providers.</param>
public ExceptionSummarizer(IEnumerable<IExceptionSummaryProvider> providers)
{
var exceptionTypesToProvidersBuilder = new Dictionary<Type, IExceptionSummaryProvider>();
Expand All @@ -35,23 +28,30 @@ public ExceptionSummarizer(IEnumerable<IExceptionSummaryProvider> providers)
_exceptionTypesToProviders = exceptionTypesToProvidersBuilder.ToFrozenDictionary();
}

/// <summary>
/// It iterates through all registered summarizers, returns a summary if possible.
/// Default is <see cref="Exception"/> message if its length is less than 32, otherwise exception type name.
/// </summary>
/// <param name="exception">The exception.</param>
/// <returns>The summary of the given <see cref="Exception"/>.</returns>
public ExceptionSummary Summarize(Exception exception)
{
_ = Throw.IfNull(exception);
var exceptionType = exception.GetType();
var exceptionTypeName = exception.GetType().Name;

// try for an exact match
if (_exceptionTypesToProviders.TryGetValue(exceptionType, out var exceptionSummaryProvider))
{
return BuildSummary(exception, exceptionSummaryProvider, exceptionTypeName);
}

// now see if there's a match for a base type
var type = exceptionType.BaseType;
while (type != null && type != typeof(object))
{
if (_exceptionTypesToProviders.TryGetValue(type, out exceptionSummaryProvider))
{
return BuildSummary(exception, exceptionSummaryProvider, exceptionTypeName);
}

type = type.BaseType;
}

// Let's see if we get lucky with the inner exception
if (exception.InnerException != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,24 @@ public void Summarize_WithDefaultHResultAndInnerException_ReturnSummary()
Assert.Equal(exceptionHResultSummary, summary);
Assert.Equal(exceptionHResultSummary.ToString(), summary.ToString());
}

private class DerivedException : TestException
{
public DerivedException(uint hResult, string message = null, Exception innerException = null)
: base(hResult, message, innerException)
{
}
}

[Fact]
public void Summarize_WithDerivedExceptionType_ReturnSummary()
{
var exception = new DerivedException(0, "Test", new TestException(0));
var exceptionHResultSummary = new ExceptionSummary("DerivedException", "TestException", "Unknown");

var summary = _exceptionSummarizer.Summarize(exception);

Assert.Equal(exceptionHResultSummary, summary);
Assert.Equal(exceptionHResultSummary.ToString(), summary.ToString());
}
}

0 comments on commit 8565028

Please sign in to comment.