Hi guys,
I have an ASP.NET core Web API that I am calling 3rd party web services. I have exception middleware in order to log exceptions and return 500 responses to hide the details from the user.
Here is where I am calling this 3rd party web service.
public static async Task<HttpResponseMessage?> CallOrder(string url, string token, WatsonOrderRequest watsonOrderRequest, IConfiguration iConfiguration)
{
HttpResponseMessage? response;
try
{
//HTTPWebRequest
var request = (HttpWebRequest)WebRequest.Create(iConfiguration.GetSection("Ezpin:Url").Value + url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.KeepAlive = false;
request.Headers.Add("Authorization", "Bearer " + token);
//Create a list of your parameters
var postParams = new List<KeyValuePair<string, string>>(){
new KeyValuePair<string, string>("sku", watsonOrderRequest.sku.ToString()) ,
new KeyValuePair<string, string>("quantity", watsonOrderRequest.quantity.ToString()),
new KeyValuePair<string, string>("pre_order", watsonOrderRequest.pre_order.ToString()),
new KeyValuePair<string, string>("price", watsonOrderRequest.price),
new KeyValuePair<string, string>("reference_code", watsonOrderRequest.reference_code.ToString())
};
var formUrlEncodedContent = new FormUrlEncodedContent(postParams);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();
await using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
await streamWriter.WriteAsync(urlEncodedString);
}
var httpResponse = (HttpWebResponse)(await request.GetResponseAsync());
response = new HttpResponseMessage
{
StatusCode = httpResponse.StatusCode,
Content = new StreamContent(httpResponse.GetResponseStream()),
};
}
catch (WebException ex)
{
//Identify error details
var resp = await new StreamReader(ex.Response!.GetResponseStream()).ReadToEndAsync();
dynamic obj = JsonConvert.DeserializeObject(resp);
var detail = obj.detail;
var code = obj.code;
response = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(detail.ToString(), System.Text.Encoding.UTF8, "application/json") };
throw new Exception(response.ToString());
}
return response;
}
Here is the exception middleware; it logs the errors and returns 500 for hiding exception details from the user.
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private static IConfiguration _configuration;
private static ILogger<ExceptionMiddleware> _logger;
public ExceptionMiddleware(RequestDelegate next, IConfiguration configuration, ILogger<ExceptionMiddleware> logger)
{
_next = next;
_configuration = configuration;
_logger = logger;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
await HandleExceptionAsync(httpContext, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
try
{
_logger.LogError("Web API Exception Handler Error: " + exception);
await using var sqlConnection =
new SqlConnection(_configuration.GetSection("ConnectionStrings:OyunPalasDbContext").Value);
await using var cmd =
new SqlCommand(
"INSERT INTO [dbo].[APIError] ([Message],[RequestMethod],[RequestUri],[TimeUtc]) VALUES (@Message, @RequestMethod, @RequestUri, @TimeUtc)",
sqlConnection);
sqlConnection.Open();
cmd.Parameters.AddWithValue("@Message", exception.Message);
cmd.Parameters.AddWithValue("@TimeUtc", DateTime.Now);
cmd.Parameters.AddWithValue("@RequestUri", context.Request.Path.ToString());
cmd.Parameters.AddWithValue("@RequestMethod", context.Request.Method.ToString());
if (exception.InnerException != null)
{
cmd.Parameters.AddWithValue("@Message", exception.Message +" " + exception.InnerException);
_logger.LogError("Web API Exception Handler Inner Error: " + exception.InnerException);
}
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
_logger.LogError("Web API Exception Handler insert error: " + e.Message);
}
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
await context.Response.WriteAsync(new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error."
}.ToString());
}
}
If this 3rd party service returns 400 bad requests, I would like to return it to the user. How can I do it?
Thank you.