Skip to content

Commit

Permalink
Added missing ConfigureAwait(false) & fixed deadlock on ValidationApi…
Browse files Browse the repository at this point in the history
…Exception.Content
  • Loading branch information
stevewgh committed Nov 26, 2018
1 parent 7a387ed commit 6d3a5f4
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 19 deletions.
18 changes: 9 additions & 9 deletions Refit.Tests/MultipartTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ public async Task MultipartUploadShouldWorkWithAnObject(Type contentSerializerTy
Assert.Equal("theObject", parts[0].Headers.ContentDisposition.Name);
Assert.Null(parts[0].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType);
var result0 = await serializer.DeserializeAsync<ModelObject>(parts[0]);
var result0 = await serializer.DeserializeAsync<ModelObject>(parts[0]).ConfigureAwait(false);
Assert.Equal(model1.Property1, result0.Property1);
Assert.Equal(model1.Property2, result0.Property2);
}
Expand Down Expand Up @@ -477,15 +477,15 @@ public async Task MultipartUploadShouldWorkWithObjects(Type contentSerializerTyp
Assert.Equal("theObjects", parts[0].Headers.ContentDisposition.Name);
Assert.Null(parts[0].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType);
var result0 = await serializer.DeserializeAsync<ModelObject>( parts[0]);
var result0 = await serializer.DeserializeAsync<ModelObject>( parts[0]).ConfigureAwait(false);
Assert.Equal(model1.Property1, result0.Property1);
Assert.Equal(model1.Property2, result0.Property2);
Assert.Equal("theObjects", parts[1].Headers.ContentDisposition.Name);
Assert.Null(parts[1].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[1].Headers.ContentType.MediaType);
var result1 = await serializer.DeserializeAsync<ModelObject>(parts[1]);
var result1 = await serializer.DeserializeAsync<ModelObject>(parts[1]).ConfigureAwait(false);
Assert.Equal(model2.Property1, result1.Property1);
Assert.Equal(model2.Property2, result1.Property2);
}
Expand Down Expand Up @@ -534,22 +534,22 @@ public async Task MultipartUploadShouldWorkWithMixedTypes()
Assert.Equal("theObjects", parts[0].Headers.ContentDisposition.Name);
Assert.Null(parts[0].Headers.ContentDisposition.FileName);
Assert.Equal("application/json", parts[0].Headers.ContentType.MediaType);
var result0 = JsonConvert.DeserializeObject<ModelObject>(await parts[0].ReadAsStringAsync());
var result0 = JsonConvert.DeserializeObject<ModelObject>(await parts[0].ReadAsStringAsync().ConfigureAwait(false));
Assert.Equal(model1.Property1, result0.Property1);
Assert.Equal(model1.Property2, result0.Property2);
Assert.Equal("theObjects", parts[1].Headers.ContentDisposition.Name);
Assert.Null(parts[1].Headers.ContentDisposition.FileName);
Assert.Equal("application/json", parts[1].Headers.ContentType.MediaType);
var result1 = JsonConvert.DeserializeObject<ModelObject>(await parts[1].ReadAsStringAsync());
var result1 = JsonConvert.DeserializeObject<ModelObject>(await parts[1].ReadAsStringAsync().ConfigureAwait(false));
Assert.Equal(model2.Property1, result1.Property1);
Assert.Equal(model2.Property2, result1.Property2);
Assert.Equal("anotherModel", parts[2].Headers.ContentDisposition.Name);
Assert.Null(parts[2].Headers.ContentDisposition.FileName);
Assert.Equal("application/json", parts[2].Headers.ContentType.MediaType);
var result2 = JsonConvert.DeserializeObject<AnotherModel>(await parts[2].ReadAsStringAsync());
var result2 = JsonConvert.DeserializeObject<AnotherModel>(await parts[2].ReadAsStringAsync().ConfigureAwait(false));
Assert.Equal(2, result2.Foos.Length);
Assert.Equal("bar1", result2.Foos[0]);
Assert.Equal("bar2", result2.Foos[1]);
Expand All @@ -567,7 +567,7 @@ public async Task MultipartUploadShouldWorkWithMixedTypes()
Assert.Equal("anEnum", parts[4].Headers.ContentDisposition.Name);
Assert.Null(parts[4].Headers.ContentDisposition.FileName);
Assert.Equal("application/json", parts[4].Headers.ContentType.MediaType);
var result4 = JsonConvert.DeserializeObject<AnEnum>(await parts[4].ReadAsStringAsync());
var result4 = JsonConvert.DeserializeObject<AnEnum>(await parts[4].ReadAsStringAsync().ConfigureAwait(false));
Assert.Equal(AnEnum.Val2, result4);
Assert.Equal("aString", parts[5].Headers.ContentDisposition.Name);
Expand All @@ -579,7 +579,7 @@ public async Task MultipartUploadShouldWorkWithMixedTypes()
Assert.Equal("anInt", parts[6].Headers.ContentDisposition.Name);
Assert.Null(parts[6].Headers.ContentDisposition.FileName);
Assert.Equal("application/json", parts[6].Headers.ContentType.MediaType);
var result6 = JsonConvert.DeserializeObject<int>(await parts[6].ReadAsStringAsync());
var result6 = JsonConvert.DeserializeObject<int>(await parts[6].ReadAsStringAsync().ConfigureAwait(false));
Assert.Equal(42, result6);
}
Expand Down Expand Up @@ -630,7 +630,7 @@ public async Task MultipartUploadShouldWorkWithHttpContent()
Assert.Equal("myName", parts[0].Headers.ContentDisposition.Name);
Assert.Equal("myFileName", parts[0].Headers.ContentDisposition.FileName);
Assert.Equal("application/custom", parts[0].Headers.ContentType.MediaType);
var result0 = await parts[0].ReadAsStringAsync();
var result0 = await parts[0].ReadAsStringAsync().ConfigureAwait(false);
Assert.Equal("some text", result0);
}
};
Expand Down
8 changes: 5 additions & 3 deletions Refit/ApiException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ public static async Task<ApiException> Create(HttpRequestMessage message, HttpMe

try
{
exception.ContentHeaders = response.Content.Headers;
exception.Content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

if (response.Content.Headers.ContentType.MediaType.Equals("application/problem+json"))
{
exception = ValidationApiException.Create(exception);
exception = await ValidationApiException.Create(exception).ConfigureAwait(false);
}
exception.ContentHeaders = response.Content.Headers;
exception.Content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

response.Content.Dispose();
}
catch
Expand Down
8 changes: 4 additions & 4 deletions Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Func<HttpClient, CancellationToken, object[], Task<T>> BuildCancellableTaskFuncF
throw new InvalidOperationException("BaseAddress must be set on the HttpClient instance");
var factory = BuildRequestFactoryForMethod(restMethod, client.BaseAddress.AbsolutePath, restMethod.CancellationToken != null);
var rq = await factory(paramList);
var rq = await factory(paramList).ConfigureAwait(false);
HttpResponseMessage resp = null;
HttpContent content = null;
var disposeResponse = true;
Expand Down Expand Up @@ -575,12 +575,12 @@ Func<object[], Task<HttpRequestMessage>> BuildRequestFactoryForMethod(RestMethod
{
foreach (var item in enumerable)
{
await AddMultipartItemAsync(multiPartContent, itemName, parameterName, item);
await AddMultipartItemAsync(multiPartContent, itemName, parameterName, item).ConfigureAwait(false);
}
}
else
{
await AddMultipartItemAsync(multiPartContent, itemName, parameterName, itemValue);
await AddMultipartItemAsync(multiPartContent, itemName, parameterName, itemValue).ConfigureAwait(false);
}
}
Expand Down Expand Up @@ -671,7 +671,7 @@ Func<HttpClient, object[], Task> BuildVoidTaskFuncForMethod(RestMethodInfo restM
throw new InvalidOperationException("BaseAddress must be set on the HttpClient instance");
var factory = BuildRequestFactoryForMethod(restMethod, client.BaseAddress.AbsolutePath, restMethod.CancellationToken != null);
var rq = await factory(paramList);
var rq = await factory(paramList).ConfigureAwait(false);
var ct = CancellationToken.None;
Expand Down
12 changes: 9 additions & 3 deletions Refit/ValidationApiException.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;

namespace Refit
{
Expand All @@ -14,19 +15,24 @@ public class ValidationApiException : ApiException
{
}

#pragma warning disable VSTHRD200 // Use "Async" suffix for async methods
/// <summary>
/// Creates a new instance of a ValidationException from an existing ApiException.
/// </summary>
/// <param name="exception">An instance of an ApiException to use to build a ValidationException.</param>
/// <returns>ValidationApiException</returns>
public static ValidationApiException Create(ApiException exception)
public static async Task<ValidationApiException> Create(ApiException exception)
#pragma warning restore VSTHRD200
{
return new ValidationApiException(exception);
return new ValidationApiException(exception)
{
Content = await exception.GetContentAsAsync<ProblemDetails>()
};
}

/// <summary>
/// The problem details of the RFC 7807 validation exception.
/// </summary>
public new ProblemDetails Content => GetContentAsAsync<ProblemDetails>().ConfigureAwait(false).GetAwaiter().GetResult();
public new ProblemDetails Content { get; private set; }
}
}

0 comments on commit 6d3a5f4

Please sign in to comment.