Skip to content

Commit 2f2e250

Browse files
[csharp-netcore][httpclient] Issues managing error statuses (#9389)
* [csharp-netcore] correct rawContent read * [csharp-netcore] avoid deserialize result when in error * [csharp-netcore] avoid aggregate exceptions * Updated samples * Updated samples * Refactored PetApiTest * Updated samples * Fixed test issues * reverted previous commit
1 parent f4f4d5d commit 2f2e250

5 files changed

Lines changed: 652 additions & 28 deletions

File tree

modules/openapi-generator/src/main/resources/csharp-netcore/libraries/httpclient/ApiClient.mustache

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ namespace {{packageName}}.Client
9898
9999
if (type == typeof(byte[])) // return byte array
100100
{
101-
return response.Content.ReadAsByteArrayAsync().Result;
101+
return response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
102102
}
103103

104104
// TODO: ? if (type.IsAssignableFrom(typeof(Stream)))
105105
if (type == typeof(Stream))
106106
{
107-
var bytes = response.Content.ReadAsByteArrayAsync().Result;
107+
var bytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
108108
if (headers != null)
109109
{
110110
var filePath = String.IsNullOrEmpty(_configuration.TempFolderPath)
@@ -128,18 +128,18 @@ namespace {{packageName}}.Client
128128

129129
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
130130
{
131-
return DateTime.Parse(response.Content.ReadAsStringAsync().Result, null, System.Globalization.DateTimeStyles.RoundtripKind);
131+
return DateTime.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), null, System.Globalization.DateTimeStyles.RoundtripKind);
132132
}
133133

134134
if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type
135135
{
136-
return Convert.ChangeType(response.Content.ReadAsStringAsync().Result, type);
136+
return Convert.ChangeType(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type);
137137
}
138138

139139
// at this point, it must be a model (json)
140140
try
141141
{
142-
return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, type, _serializerSettings);
142+
return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type, _serializerSettings);
143143
}
144144
catch (Exception e)
145145
{
@@ -401,10 +401,10 @@ namespace {{packageName}}.Client
401401
partial void InterceptRequest(HttpRequestMessage req);
402402
partial void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response);
403403

404-
private ApiResponse<T> ToApiResponse<T>(HttpResponseMessage response, object responseData, Uri uri)
404+
private async Task<ApiResponse<T>> ToApiResponse<T>(HttpResponseMessage response, object responseData, Uri uri)
405405
{
406406
T result = (T) responseData;
407-
string rawContent = response.Content.ToString();
407+
string rawContent = await response.Content.ReadAsStringAsync();
408408
409409
var transformed = new ApiResponse<T>(response.StatusCode, new Multimap<string, string>({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent)
410410
{
@@ -446,7 +446,7 @@ namespace {{packageName}}.Client
446446

447447
private ApiResponse<T> Exec<T>(HttpRequestMessage req, IReadableConfiguration configuration)
448448
{
449-
return ExecAsync<T>(req, configuration).Result;
449+
return ExecAsync<T>(req, configuration).GetAwaiter().GetResult();
450450
}
451451

452452
private async Task<ApiResponse<T>> ExecAsync<T>(HttpRequestMessage req,
@@ -511,6 +511,11 @@ namespace {{packageName}}.Client
511511
}
512512
{{/supportsRetry}}
513513

514+
if (!response.IsSuccessStatusCode)
515+
{
516+
return await ToApiResponse<T>(response, default(T), req.RequestUri);
517+
}
518+
514519
object responseData = deserializer.Deserialize<T>(response);
515520

516521
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
@@ -525,9 +530,7 @@ namespace {{packageName}}.Client
525530

526531
InterceptResponse(req, response);
527532

528-
var result = ToApiResponse<T>(response, responseData, req.RequestUri);
529-
530-
return result;
533+
return await ToApiResponse<T>(response, responseData, req.RequestUri);
531534
}
532535

533536
{{#supportsAsync}}

samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class PetApiTests : IDisposable
3636
private PetApi instance;
3737

3838
private long petId = 11088;
39+
private long notExsistentPetId = 99999;
3940

4041
/// <summary>
4142
/// Create a Pet object
@@ -204,6 +205,25 @@ public void TestGetPetByIdAsync()
204205
Assert.Equal("sample category name2", response.Category.Name);
205206
}
206207

208+
/// <summary>
209+
/// Test GetPetById on an not existent Id
210+
/// </summary>
211+
[Fact]
212+
public void TestGetPetById_TestException()
213+
{
214+
PetApi petApi = new PetApi();
215+
216+
var exception = Assert.Throws<ApiException>(() =>
217+
{
218+
petApi.GetPetById(notExsistentPetId);
219+
});
220+
221+
Assert.IsType<ApiException>(exception);
222+
Assert.Equal(404, exception.ErrorCode);
223+
Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent);
224+
Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message);
225+
}
226+
207227
/* a simple test for binary response. no longer in use.
208228
[Fact]
209229
public void TestGetByIdBinaryResponse()
@@ -247,7 +267,25 @@ public void TestGetPetByIdWithHttpInfoAsync()
247267
Assert.Equal(56, response.Category.Id);
248268
Assert.Equal("sample category name2", response.Category.Name);
249269
}
250-
270+
271+
[Fact]
272+
public void TestGetPetByIdWithHttpInfoAsync_Test404Response()
273+
{
274+
PetApi petApi = new PetApi();
275+
petApi.ExceptionFactory = null;
276+
var response = petApi.GetPetByIdWithHttpInfoAsync(notExsistentPetId).Result;
277+
Pet result = response.Data;
278+
279+
Assert.IsType<ApiResponse<Pet>>(response);
280+
Assert.Equal(404, (int)response.StatusCode);
281+
Assert.True(response.Headers.ContainsKey("Content-Type"));
282+
Assert.Equal("application/json", response.Headers["Content-Type"][0]);
283+
284+
Assert.Null(result);
285+
Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", response.RawContent);
286+
Assert.Equal("Not Found", response.ErrorText);
287+
}
288+
251289
/// <summary>
252290
/// Test UpdatePet
253291
/// </summary>

0 commit comments

Comments
 (0)