Skip to content

Commit

Permalink
Fix for #1692 (#1511) and use charset for #1693
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Jan 11, 2022
1 parent b2031e0 commit c7eebdf
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 31 deletions.
4 changes: 2 additions & 2 deletions src/RestSharp/Response/ResponseHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace RestSharp;

static class ResponseHandling {
public static string GetResponseString(this HttpResponseMessage response, byte[] bytes) {
var encodingString = response.Content.Headers.ContentEncoding.FirstOrDefault();
var encodingString = response.Content.Headers.ContentType?.CharSet;
var encoding = encodingString != null ? TryGetEncoding(encodingString) : Encoding.Default;
return encoding.GetString(bytes);

Expand All @@ -37,7 +37,7 @@ Encoding TryGetEncoding(string es) {
#if NETSTANDARD
return response.Content.ReadAsStreamAsync();
# else
return response.Content.ReadAsStreamAsync(cancellationToken);
return response.Content.ReadAsStreamAsync(cancellationToken)!;
#endif
}
}
11 changes: 9 additions & 2 deletions src/RestSharp/Response/RestResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ CancellationToken cancellationToken
async Task<RestResponse> GetDefaultResponse() {
var readTask = request.ResponseWriter == null ? ReadResponse() : ReadAndConvertResponse();
using var stream = await readTask.ConfigureAwait(false);
var bytes = stream == null ? null : await stream.ReadAsBytes(cancellationToken).ConfigureAwait(false);
var content = bytes == null ? null : httpResponse.GetResponseString(bytes);

var bytes = stream == null ? null : await stream.ReadAsBytes(cancellationToken).ConfigureAwait(false);
var content = bytes == null ? null : httpResponse.GetResponseString(bytes);

return new RestResponse {
Content = content,
Expand All @@ -80,6 +81,7 @@ async Task<RestResponse> GetDefaultResponse() {
ContentLength = httpResponse.Content.Headers.ContentLength,
ContentType = httpResponse.Content.Headers.ContentType?.MediaType,
ResponseStatus = httpResponse.IsSuccessStatusCode ? ResponseStatus.Completed : ResponseStatus.Error,
ErrorException = MaybeException(),
ResponseUri = httpResponse.RequestMessage!.RequestUri,
Server = httpResponse.Headers.Server.ToString(),
StatusCode = httpResponse.StatusCode,
Expand All @@ -91,6 +93,11 @@ async Task<RestResponse> GetDefaultResponse() {
Cookies = cookieCollection
};

Exception? MaybeException()
=> httpResponse.IsSuccessStatusCode
? null
: new HttpRequestException($"Request failed with status code {httpResponse.StatusCode}");

Task<Stream?> ReadResponse() => httpResponse.ReadResponse(cancellationToken);

async Task<Stream?> ReadAndConvertResponse() {
Expand Down
19 changes: 9 additions & 10 deletions src/RestSharp/RestClient.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ public async Task<RestResponse> ExecuteAsync(RestRequest request, CancellationTo
cancellationToken
)
.ConfigureAwait(false)
: ReturnErrorOrThrow(response, internalResponse.Exception, internalResponse.TimeoutToken);
: AddError(response, internalResponse.Exception, internalResponse.TimeoutToken);


response.Request = request;
response.Request.IncreaseNumAttempts();
return response;

return Options.ThrowOnAnyError ? ThrowIfError(response) : response;
}

async Task<InternalResponse> ExecuteInternal(RestRequest request, CancellationToken cancellationToken) {
Expand Down Expand Up @@ -120,18 +122,15 @@ record InternalResponse(HttpResponseMessage? ResponseMessage, Uri Url, Exception
return stream == null ? null : await stream.ReadAsBytes(cancellationToken).ConfigureAwait(false);
}

RestResponse ReturnErrorOrThrow(RestResponse response, Exception exception, CancellationToken timeoutToken) {
if (exception is OperationCanceledException) {
response.ResponseStatus = timeoutToken.IsCancellationRequested ? ResponseStatus.TimedOut : ResponseStatus.Aborted;
}
else {
response.ResponseStatus = ResponseStatus.Error;
}
static RestResponse AddError(RestResponse response, Exception exception, CancellationToken timeoutToken) {
response.ResponseStatus = exception is OperationCanceledException
? timeoutToken.IsCancellationRequested ? ResponseStatus.TimedOut : ResponseStatus.Aborted
: ResponseStatus.Error;

response.ErrorMessage = exception.Message;
response.ErrorException = exception;

return Options.ThrowOnAnyError ? ThrowIfError(response) : response;
return response;
}

static RestResponse ThrowIfError(RestResponse response) {
Expand Down
61 changes: 61 additions & 0 deletions test/RestSharp.IntegrationTests/RequestFailureTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Net;
using RestSharp.IntegrationTests.Fixtures;

namespace RestSharp.IntegrationTests;

[Collection(nameof(TestServerCollection))]
public class RequestFailureTests {
readonly RestClient _client;
readonly TestServerFixture _fixture;

public RequestFailureTests(TestServerFixture fixture) {
_client = new RestClient(fixture.Server.Url);
_fixture = fixture;
}

[Fact]
public async Task Handles_GET_Request_Errors() {
var request = new RestRequest("status?code=404");
var response = await _client.ExecuteAsync(request);

response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}

[Fact]
public async Task Handles_GET_Request_Errors_With_Response_Type() {
var request = new RestRequest("status?code=404");
var response = await _client.ExecuteAsync<Response>(request);

response.StatusCode.Should().Be(HttpStatusCode.NotFound);
response.Data.Should().Be(null);
}

[Fact]
public async Task Throws_on_unsuccessful_call() {
var client = new RestClient(new RestClientOptions(_fixture.Server.Url) { ThrowOnAnyError = true });
var request = new RestRequest("status?code=404");

var task = () => client.ExecuteAsync<Response>(request);
await task.Should().ThrowExactlyAsync<HttpRequestException>();
}

[Fact]
public async Task GetAsync_throws_on_unsuccessful_call() {
var request = new RestRequest("status?code=404");

var task = () => _client.GetAsync(request);
await task.Should().ThrowExactlyAsync<HttpRequestException>();
}

[Fact]
public async Task GetAsync_generic_throws_on_unsuccessful_call() {
var request = new RestRequest("status?code=404");

var task = () => _client.GetAsync<Response>(request);
await task.Should().ThrowExactlyAsync<HttpRequestException>();
}

class Response {
public string Message { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,4 @@ public async Task Can_Timeout_GET_Async() {

Assert.Equal(ResponseStatus.TimedOut, response.ResponseStatus);
}

[Fact]
public async Task Handles_GET_Request_Errors_Async() {
var request = new RestRequest("status?code=404");
var response = await _client.ExecuteAsync(request);

Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

[Fact]
public async Task Handles_GET_Request_Errors_Async_With_Response_Type() {
var request = new RestRequest("status?code=404");
var response = await _client.ExecuteAsync<Response>(request);

Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
Assert.Null(response.Data);
}
}

0 comments on commit c7eebdf

Please sign in to comment.