Skip to content

Commit

Permalink
Improve diagnostics for IDestinationResolver exceptions (#2241)
Browse files Browse the repository at this point in the history
* Improve diagnostics for IDestinationResolver exceptions

* Update src/ReverseProxy/ServiceDiscovery/DnsDestinationResolver.cs

Co-authored-by: Chris Ross <Tratcher@Outlook.com>

---------

Co-authored-by: Chris Ross <Tratcher@Outlook.com>
  • Loading branch information
ReubenBond and Tratcher committed Sep 5, 2023
1 parent 47f1e7c commit e861e93
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
12 changes: 11 additions & 1 deletion src/ReverseProxy/Management/ProxyConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,17 @@ private async ValueTask<IProxyConfig> LoadConfigAsyncCore(IProxyConfig config, C
{
foreach (var (i, task) in resolverTasks)
{
var resolvedDestinations = await task;
ResolvedDestinationCollection resolvedDestinations;
try
{
resolvedDestinations = await task;
}
catch (Exception exception)
{
var cluster = clusters[i];
throw new InvalidOperationException($"Error resolving destinations for cluster {cluster.ClusterId}", exception);
}

clusters[i] = clusters[i] with { Destinations = resolvedDestinations.Destinations };
if (resolvedDestinations.ChangeToken is { } token)
{
Expand Down
18 changes: 14 additions & 4 deletions src/ReverseProxy/ServiceDiscovery/DnsDestinationResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,21 @@ public async ValueTask<ResolvedDestinationCollection> ResolveDestinationsAsync(I
{
var originalUri = new Uri(originalConfig.Address);
var originalHost = originalConfig.Host is { Length: > 0 } host ? host : originalUri.Authority;
var addresses = options.AddressFamily switch
var hostName = originalUri.DnsSafeHost;
IPAddress[] addresses;
try
{
{ } addressFamily => await Dns.GetHostAddressesAsync(originalUri.DnsSafeHost, addressFamily, cancellationToken).ConfigureAwait(false),
null => await Dns.GetHostAddressesAsync(originalUri.DnsSafeHost, cancellationToken).ConfigureAwait(false)
};
addresses = options.AddressFamily switch
{
{ } addressFamily => await Dns.GetHostAddressesAsync(hostName, addressFamily, cancellationToken).ConfigureAwait(false),
null => await Dns.GetHostAddressesAsync(hostName, cancellationToken).ConfigureAwait(false)
};
}
catch (Exception exception)
{
throw new InvalidOperationException($"Failed to resolve host '{hostName}'. See {nameof(Exception.InnerException)} for details.", exception);
}

var results = new List<(string Name, DestinationConfig Config)>(addresses.Length);
var uriBuilder = new UriBuilder(originalUri);
var healthUri = originalConfig.Health is { Length: > 0 } health ? new Uri(health) : null;
Expand Down
12 changes: 8 additions & 4 deletions test/ReverseProxy.Tests/Management/ProxyConfigManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,8 +1392,10 @@ public async Task LoadAsync_DestinationResolver_Initial_ThrowsAsync()
var ioEx = await Assert.ThrowsAsync<InvalidOperationException>(() => configManager.InitialLoadAsync());
Assert.Equal("Unable to load or apply the proxy configuration.", ioEx.Message);

var innerExc = Assert.IsType<InvalidOperationException>(ioEx.InnerException);
Assert.Equal("Throwing!", innerExc.Message);
var innerExc1 = Assert.IsType<InvalidOperationException>(ioEx.InnerException);
Assert.Equal("Error resolving destinations for cluster cluster1", innerExc1.Message);
var innerExc2 = Assert.IsType<InvalidOperationException>(innerExc1.InnerException);
Assert.Equal("Throwing!", innerExc2.Message);
}

[Fact]
Expand Down Expand Up @@ -1640,7 +1642,9 @@ public async Task LoadAsync_DestinationResolver_Reload_ThrowsAsync()

// Read the failure event
var configLoadException = Assert.IsType<TestConfigChangeListener.ConfigurationLoadingFailedEvent>(await configListener.Events.Reader.ReadAsync());
var ex = configLoadException.Exception;
Assert.Equal("Throwing!", ex.Message);
var innerExc1 = Assert.IsType<InvalidOperationException>(configLoadException.Exception);
Assert.Equal("Error resolving destinations for cluster cluster1", innerExc1.Message);
var innerExc2 = Assert.IsType<InvalidOperationException>(innerExc1.InnerException);
Assert.Equal("Throwing!", innerExc2.Message);
}
}

0 comments on commit e861e93

Please sign in to comment.