Skip to content

Commit 3b3800b

Browse files
Cherry pick grpc exception handling change to 0.11 (#431)
* grpc exception handling sample (#427) * rpc exception handling * Upgrade grpc to 2.32.0 (#413) * fix comment Co-authored-by: Young Bu Park <[email protected]>
1 parent ec015be commit 3b3800b

File tree

6 files changed

+98
-7
lines changed

6 files changed

+98
-7
lines changed

samples/AspNetCore/ControllerSample/Controllers/SampleController.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,17 @@ public async Task<ActionResult<Account>> Withdraw(Transaction transaction, [From
8080
await state.SaveAsync();
8181
return state.Value;
8282
}
83+
84+
/// <summary>
85+
/// Method for returning a BadRequest result which will cause Dapr sidecar to throw an RpcException
86+
/// </summary>
87+
[HttpPost("throwException")]
88+
public async Task<ActionResult<Account>> ThrowException(Transaction transaction, [FromServices] DaprClient daprClient)
89+
{
90+
Console.WriteLine("Enter ThrowException");
91+
var task = Task.Delay(10);
92+
await task;
93+
return BadRequest(new { statusCode = 400, message = "bad request" });
94+
}
8395
}
8496
}

samples/Client/DaprClient/DaprClient.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@
99
<ProjectReference Include="..\..\..\src\Dapr.Client\Dapr.Client.csproj" />
1010
</ItemGroup>
1111

12+
<ItemGroup>
13+
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
14+
<PackageReference Include="Google.Api.CommonProtos" Version="2.2.0" />
15+
</ItemGroup>
16+
1217
</Project>

samples/Client/DaprClient/Program.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace DaprClient
1111
using System.Threading.Tasks;
1212
using Dapr.Client;
1313
using Dapr.Client.Http;
14+
using Grpc.Core;
1415

1516
/// <summary>
1617
/// Shows Dapr client calls.
@@ -20,6 +21,10 @@ public class Program
2021
private static readonly string stateKeyName = "mykey";
2122
private static readonly string storeName = "statestore";
2223
private static readonly string pubsubName = "pubsub";
24+
private static readonly string daprErrorInfoHTTPCodeMetadata = "http.code";
25+
private static readonly string daprErrorInfoHTTPErrorMetadata = "http.error_message";
26+
private static readonly string grpcStatusDetails = "grpc-status-details-bin";
27+
private static readonly string grpcErrorInfoDetail = "google.rpc.ErrorInfo";
2328

2429
/// <summary>
2530
/// Main entry point.
@@ -55,6 +60,12 @@ public static async Task Main(string[] args)
5560
// Read State
5661
await GetStateAfterTransactionAsync(client);
5762

63+
if (args.Length > 0 && args[0] == "rpc-exception")
64+
{
65+
// Invoke /throwException route on the Controller sample server
66+
await InvokeThrowExceptionOperationAsync(client);
67+
}
68+
5869
#region Service Invoke - Required RoutingService
5970
//// This provides an example of how to invoke a method on another REST service that is listening on http.
6071
//// To use it run RoutingService in this solution.
@@ -209,6 +220,39 @@ internal static async Task InvokeBalanceServiceOperationAsync(DaprClient client)
209220
Console.WriteLine($"Received balance {res.Balance}");
210221
}
211222

223+
internal static async Task InvokeThrowExceptionOperationAsync(DaprClient client)
224+
{
225+
Console.WriteLine("Invoking ThrowException");
226+
var data = new { id = "17", amount = (decimal)10, };
227+
228+
HTTPExtension httpExtension = new HTTPExtension()
229+
{
230+
Verb = HTTPVerb.Post
231+
};
232+
233+
try
234+
{
235+
// Invokes a POST method named "throwException" that takes input of type "Transaction" as defined in the ControllerSample.
236+
await client.InvokeMethodAsync("controller", "throwException", data, httpExtension);
237+
}
238+
catch (RpcException ex)
239+
{
240+
var entry = ex.Trailers.Get(grpcStatusDetails);
241+
var status = Google.Rpc.Status.Parser.ParseFrom(entry.ValueBytes);
242+
Console.WriteLine("Grpc Exception Message: " + status.Message);
243+
Console.WriteLine("Grpc Statuscode: " + status.Code);
244+
foreach(var detail in status.Details)
245+
{
246+
if(Google.Protobuf.WellKnownTypes.Any.GetTypeName(detail.TypeUrl) == grpcErrorInfoDetail)
247+
{
248+
var rpcError = detail.Unpack<Google.Rpc.ErrorInfo>();
249+
Console.WriteLine("Grpc Exception: Http Error Message: " + rpcError.Metadata[daprErrorInfoHTTPErrorMetadata]);
250+
Console.WriteLine("Grpc Exception: Http Status Code: " + rpcError.Metadata[daprErrorInfoHTTPCodeMetadata]);
251+
}
252+
}
253+
}
254+
}
255+
212256
private class Widget
213257
{
214258
public string Size { get; set; }

samples/Client/DaprClient/Readme.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,33 @@ The method *PublishDepositeEventToRoutingSampleAsync* demonstrates how to publis
115115
```c#
116116
await client.PublishEventAsync("deposit", new { id = "17", amount = (decimal)10, });
117117
```
118+
119+
120+
## Handling RpcException
121+
122+
Run the controller sample as follows from samples/AspNetCore/ControllerSample directory:-
123+
```
124+
dapr run --app-id controller --app-port 5000 dotnet run
125+
```
126+
127+
Run the client sample as follows from samples/Client/DaprClient directory. The "rpc-exception" argument invokes a route on the server side that causes it to throw an RpcException:-
128+
```
129+
dapr run --app-id gRPC_Client dotnet run rpc-exception
130+
```
131+
132+
The controller sample has a route "/throwException" that returns a BadRequest result which causes the Dapr sidecar to throw an RpcException. The method *InvokeThrowExceptionOperationAsync* on the client side demonstrates how to extract the error message from RpcException.
133+
```c#
134+
var entry = ex.Trailers.Get(grpcStatusDetails);
135+
var status = Google.Rpc.Status.Parser.ParseFrom(entry.ValueBytes);
136+
Console.WriteLine("Grpc Exception Message: " + status.Message);
137+
Console.WriteLine("Grpc Statuscode: " + status.Code);
138+
foreach(var detail in status.Details)
139+
{
140+
if(Google.Protobuf.WellKnownTypes.Any.GetTypeName(detail.TypeUrl) == grpcErrorInfoDetail)
141+
{
142+
var rpcError = detail.Unpack<Google.Rpc.ErrorInfo>();
143+
Console.WriteLine("Grpc Exception: Http Error Message: " + rpcError.Metadata[daprErrorInfoHTTPErrorMetadata]);
144+
Console.WriteLine("Grpc Exception: Http Status Code: " + rpcError.Metadata[daprErrorInfoHTTPCodeMetadata]);
145+
}
146+
}
147+
```

src/Dapr.Client/Dapr.Client.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
<Description>This package contains the reference assemblies for developing services using Dapr.</Description>
1515
</PropertyGroup>
1616
<ItemGroup>
17-
<PackageReference Include="Google.Protobuf" Version="3.11.4" />
18-
<PackageReference Include="Grpc.Net.Client" Version="2.27.0" />
19-
<PackageReference Include="Grpc.Tools" Version="2.27.0" PrivateAssets="All" />
17+
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
18+
<PackageReference Include="Grpc.Net.Client" Version="2.32.0" />
19+
<PackageReference Include="Grpc.Tools" Version="2.32.0" PrivateAssets="All" />
2020
</ItemGroup>
2121
<ItemGroup>
2222
<Folder Include="Protos\" />

test/Dapr.Client.Test/Dapr.Client.Test.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
<ItemGroup>
77
<PackageReference Include="FluentAssertions" Version="5.9.0" />
8-
<PackageReference Include="Google.Protobuf" Version="3.11.4" />
9-
<PackageReference Include="Grpc.Core.Testing" Version="2.31.0-pre1" />
10-
<PackageReference Include="Grpc.Net.Client" Version="2.27.0" />
11-
<PackageReference Include="Grpc.Tools" Version="2.27.0" PrivateAssets="All" />
8+
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
9+
<PackageReference Include="Grpc.Core.Testing" Version="2.32.0" />
10+
<PackageReference Include="Grpc.Net.Client" Version="2.32.0" />
11+
<PackageReference Include="Grpc.Tools" Version="2.32.0" PrivateAssets="All" />
1212
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
1313
<PackageReference Include="xunit" Version="2.4.1" />
1414
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">

0 commit comments

Comments
 (0)