Skip to content

Commit 16f6b49

Browse files
authored
Unwrap exceptions in instrumented LROs (Azure#20540)
1 parent 46bc342 commit 16f6b49

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

sdk/core/Azure.Core.TestFramework/src/OperationInterceptor.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Linq;
66
using System.Reflection;
7+
using System.Runtime.ExceptionServices;
78
using System.Threading;
89
using Castle.DynamicProxy;
910

@@ -31,15 +32,29 @@ public void Intercept(IInvocation invocation)
3132
CheckArguments(invocation.Arguments);
3233
var cancellationToken = invocation.Arguments.Last();
3334
var waitForCompletionMethod = invocation.TargetType.GetMethod(WaitForCompletionMethodName, new[]{typeof(TimeSpan), typeof(CancellationToken)});
34-
invocation.ReturnValue = waitForCompletionMethod.Invoke(invocation.InvocationTarget, new[] {NoWaitDelay, cancellationToken});
35+
try
36+
{
37+
invocation.ReturnValue = waitForCompletionMethod.Invoke(invocation.InvocationTarget, new[] {NoWaitDelay, cancellationToken});
38+
}
39+
catch (TargetInvocationException ex)
40+
{
41+
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
42+
}
3543
return;
3644
}
3745

3846
if (invocation.Method.Name == WaitForCompletionResponseAsync.Name)
3947
{
4048
CheckArguments(invocation.Arguments);
4149
var cancellationToken = invocation.Arguments.Last();
42-
invocation.ReturnValue = WaitForCompletionResponseAsync.Invoke(invocation.InvocationTarget, new[] {NoWaitDelay, cancellationToken});
50+
try
51+
{
52+
invocation.ReturnValue = WaitForCompletionResponseAsync.Invoke(invocation.InvocationTarget, new[] {NoWaitDelay, cancellationToken});
53+
}
54+
catch (TargetInvocationException ex)
55+
{
56+
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
57+
}
4358
return;
4459
}
4560
}

sdk/core/Azure.Core/tests/RecordedTestBaseTests.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
76
using System.Threading;
87
using System.Threading.Tasks;
98
using Azure.Core.TestFramework;
@@ -80,21 +79,42 @@ public async Task WaitForCompletionWaitsDuringLive()
8079
Assert.AreEqual(TimeSpan.FromSeconds(10), original.WaitForCompletionCalls[3]);
8180
}
8281

82+
[Test]
83+
public async Task WaitForCompletionErrorsArePropagated()
84+
{
85+
var client = InstrumentClient(new RecordedClient());
86+
87+
var operation = await client.StartOperationAsync(true);
88+
89+
Assert.ThrowsAsync<RequestFailedException>(async () => await operation.WaitForCompletionAsync());
90+
}
91+
8392
public class RecordedClient
8493
{
85-
public virtual Task<CustomOperation> StartOperationAsync()
94+
public virtual Task<CustomOperation> StartOperationAsync(bool throwOnWait = false)
8695
{
87-
return Task.FromResult(new CustomOperation());
96+
return Task.FromResult(new CustomOperation(throwOnWait));
8897
}
8998

90-
public virtual CustomOperation StartOperation()
99+
public virtual CustomOperation StartOperation(bool throwOnWait = false)
91100
{
92-
return new CustomOperation();
101+
return new CustomOperation(throwOnWait);
93102
}
94103
}
95104

96105
public class CustomOperation : Operation<int>
97106
{
107+
private readonly bool _throwOnWait;
108+
109+
public CustomOperation(bool throwOnWait)
110+
{
111+
_throwOnWait = throwOnWait;
112+
}
113+
114+
protected CustomOperation()
115+
{
116+
}
117+
98118
public virtual List<TimeSpan?> WaitForCompletionCalls { get; } = new();
99119
public override string Id { get; }
100120
public override Response GetRawResponse()
@@ -123,6 +143,10 @@ public override ValueTask<Response<int>> WaitForCompletionAsync(CancellationToke
123143
public override ValueTask<Response<int>> WaitForCompletionAsync(TimeSpan pollingInterval, CancellationToken cancellationToken)
124144
{
125145
WaitForCompletionCalls.Add(pollingInterval);
146+
if (_throwOnWait)
147+
{
148+
throw new RequestFailedException(400, "Operation failed");
149+
}
126150
return new(Response.FromValue(0, new MockResponse(200)));
127151
}
128152
}

0 commit comments

Comments
 (0)