Skip to content

Commit

Permalink
Dispose client on getting an Object Disposed exception (#1211) (#1251)
Browse files Browse the repository at this point in the history
  • Loading branch information
varunpuranik authored and myagley committed May 24, 2019
1 parent 1ac1e94 commit e458e14
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ namespace Microsoft.Azure.Devices.Edge.Hub.CloudProxy
using Microsoft.Azure.Devices.Edge.Hub.Core;
using Microsoft.Azure.Devices.Edge.Hub.Core.Cloud;
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Azure.Devices.Routing.Core.Query;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using static System.FormattableString;

class CloudProxy : ICloudProxy
{
static readonly Type[] NonRecoverableExceptions =
{
typeof(NullReferenceException),
typeof(ObjectDisposedException)
};

readonly IClient client;
readonly IMessageConverterProvider messageConverterProvider;
readonly Action<string, CloudConnectionStatus> connectionStatusChangedHandler;
Expand Down Expand Up @@ -259,9 +266,9 @@ Task HandleException(Exception ex)
{
this.connectionStatusChangedHandler(this.clientId, CloudConnectionStatus.DisconnectedTokenExpired);
}
else if (ex is NullReferenceException)
else if (NonRecoverableExceptions.Any(nre => nre.IsInstanceOfType(ex)))
{
Events.HandleNre(this);
Events.HandleNre(ex, this);
return this.CloseAsync();
}
}
Expand Down Expand Up @@ -556,9 +563,9 @@ public static void ErrorGettingTwin(CloudProxy cloudProxy, Exception ex)
Log.LogDebug((int)EventIds.ErrorGettingTwin, ex, Invariant($"Error getting twin for {cloudProxy.clientId} in cloud proxy {cloudProxy.id}"));
}

public static void HandleNre(CloudProxy cloudProxy)
public static void HandleNre(Exception ex, CloudProxy cloudProxy)
{
Log.LogDebug((int)EventIds.HandleNre, Invariant($"Got a NullReferenceException from client for {cloudProxy.clientId}. Closing the cloud proxy since it may be in a bad state."));
Log.LogDebug((int)EventIds.HandleNre, ex, Invariant($"Got a non-recoverable error from client for {cloudProxy.clientId}. Closing the cloud proxy since it may be in a bad state."));
}

internal static void ExceptionInHandleException(CloudProxy cloudProxy, Exception handlingException, Exception caughtException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,10 @@ public async Task TestCloseThrows()
client.VerifyAll();
}

[Fact]
public async Task TestHandlNre()
[Theory]
[InlineData(typeof(NullReferenceException))]
[InlineData(typeof(ObjectDisposedException))]
public async Task TestHandleNonRecoverableExceptions(Type exceptionType)
{
// Arrange
var messageConverter = Mock.Of<IMessageConverter<Message>>(m => m.FromMessage(It.IsAny<IMessage>()) == new Message());
Expand All @@ -202,13 +204,13 @@ public async Task TestHandlNre()
TimeSpan idleTimeout = TimeSpan.FromSeconds(60);
Action<string, CloudConnectionStatus> connectionStatusChangedHandler = (s, status) => { };
var client = new Mock<IClient>(MockBehavior.Strict);
client.Setup(c => c.SendEventAsync(It.IsAny<Message>())).ThrowsAsync(new NullReferenceException());
client.Setup(c => c.SendEventAsync(It.IsAny<Message>())).ThrowsAsync((Exception)Activator.CreateInstance(exceptionType, "dummy message"));
client.Setup(c => c.CloseAsync()).Returns(Task.CompletedTask);
var cloudProxy = new CloudProxy(client.Object, messageConverterProvider, clientId, connectionStatusChangedHandler, cloudListener, idleTimeout, false);
IMessage message = new EdgeMessage.Builder(new byte[0]).Build();

// Act
await Assert.ThrowsAsync<NullReferenceException>(() => cloudProxy.SendMessageAsync(message));
await Assert.ThrowsAsync(exceptionType, () => cloudProxy.SendMessageAsync(message));

// Assert.
client.VerifyAll();
Expand Down

0 comments on commit e458e14

Please sign in to comment.