refit/Refit/ApiException.cs

91 строка
4.0 KiB
C#
Исходник Обычный вид История

2017-06-21 18:58:02 +03:00
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace Refit
{
2018-10-06 02:22:52 +03:00
[Serializable]
2017-06-21 18:58:02 +03:00
public class ApiException : Exception
{
2018-01-28 20:50:46 +03:00
public HttpStatusCode StatusCode { get; }
public string ReasonPhrase { get; }
public HttpResponseHeaders Headers { get; }
public HttpMethod HttpMethod { get; }
public Uri Uri => RequestMessage.RequestUri;
public HttpRequestMessage RequestMessage { get; }
2017-06-21 18:58:02 +03:00
public HttpContentHeaders ContentHeaders { get; private set; }
public string Content { get; private set; }
public bool HasContent => !string.IsNullOrWhiteSpace(Content);
public RefitSettings RefitSettings { get; set; }
protected ApiException(HttpRequestMessage message, HttpMethod httpMethod, string content, HttpStatusCode statusCode, string reasonPhrase, HttpResponseHeaders headers, RefitSettings refitSettings = null) :
this(CreateMessage(statusCode, reasonPhrase), message, httpMethod, content, statusCode, reasonPhrase, headers, refitSettings)
{
}
protected ApiException(string exceptionMessage, HttpRequestMessage message, HttpMethod httpMethod, string content, HttpStatusCode statusCode, string reasonPhrase, HttpResponseHeaders headers, RefitSettings refitSettings = null) :
base(exceptionMessage)
2017-06-21 18:58:02 +03:00
{
2018-01-28 20:50:46 +03:00
RequestMessage = message;
2017-06-21 18:58:02 +03:00
HttpMethod = httpMethod;
StatusCode = statusCode;
ReasonPhrase = reasonPhrase;
Headers = headers;
RefitSettings = refitSettings;
Content = content;
2017-06-21 18:58:02 +03:00
}
public async Task<T> GetContentAsAsync<T>() => HasContent ?
await RefitSettings.ContentSerializer.DeserializeAsync<T>(new StringContent(Content)).ConfigureAwait(false) :
2018-01-28 00:50:46 +03:00
default;
2017-06-21 18:58:02 +03:00
#pragma warning disable VSTHRD200 // Use "Async" suffix for async methods
public static Task<ApiException> Create(HttpRequestMessage message, HttpMethod httpMethod, HttpResponseMessage response, RefitSettings refitSettings = null)
#pragma warning restore VSTHRD200 // Use "Async" suffix for async methods
{
var exceptionMessage = CreateMessage(response.StatusCode, response.ReasonPhrase);
return Create(exceptionMessage, message, httpMethod, response, refitSettings);
}
#pragma warning disable VSTHRD200 // Use "Async" suffix for async methods
public static async Task<ApiException> Create(string exceptionMessage, HttpRequestMessage message, HttpMethod httpMethod, HttpResponseMessage response, RefitSettings refitSettings = null)
2017-06-21 18:58:02 +03:00
#pragma warning restore VSTHRD200 // Use "Async" suffix for async methods
{
var exception = new ApiException(exceptionMessage, message, httpMethod, null, response.StatusCode, response.ReasonPhrase, response.Headers, refitSettings);
2017-06-21 18:58:02 +03:00
if (response.Content == null)
{
2017-06-21 18:58:02 +03:00
return exception;
}
2017-06-21 18:58:02 +03:00
2018-01-28 20:50:46 +03:00
try
{
exception.ContentHeaders = response.Content.Headers;
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
exception.Content = content;
if (response.Content.Headers?.ContentType?.MediaType?.Equals("application/problem+json") ?? false)
{
exception = ValidationApiException.Create(exception);
}
2017-06-21 18:58:02 +03:00
response.Content.Dispose();
2018-01-28 20:50:46 +03:00
}
catch
{
2017-06-21 18:58:02 +03:00
// NB: We're already handling an exception at this point,
// so we want to make sure we don't throw another one
// that hides the real error.
}
return exception;
}
2019-02-17 01:11:56 +03:00
static string CreateMessage(HttpStatusCode statusCode, string reasonPhrase) =>
2018-01-14 22:58:24 +03:00
$"Response status code does not indicate success: {(int)statusCode} ({reasonPhrase}).";
2017-06-21 18:58:02 +03:00
}
}