Browse Source

Merge pull request #140 from dotnet/#42-Global-exception-handling

#42 global exception handling
pull/142/head
David Sanz 7 years ago
committed by GitHub
parent
commit
51c1fd658f
22 changed files with 297 additions and 47 deletions
  1. +18
    -0
      src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs
  2. +24
    -0
      src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs
  3. +67
    -0
      src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
  4. +6
    -1
      src/Services/Basket/Basket.API/Startup.cs
  5. +18
    -0
      src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs
  6. +24
    -0
      src/Services/Catalog/Catalog.API/Infrastructure/Exceptions/CatalogDomainException.cs
  7. +63
    -0
      src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
  8. +8
    -9
      src/Services/Catalog/Catalog.API/Startup.cs
  9. +1
    -4
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
  10. +2
    -2
      src/Services/Ordering/Ordering.API/Application/Commands/IdentifierCommandHandler.cs
  11. +6
    -3
      src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs
  12. +2
    -7
      src/Services/Ordering/Ordering.API/Startup.cs
  13. +5
    -4
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs
  14. +5
    -4
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs
  15. +3
    -2
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs
  16. +23
    -0
      src/Services/Ordering/Ordering.Domain/Exceptions/OrderingDomainException.cs
  17. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs
  18. +2
    -2
      src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
  19. +2
    -1
      src/Services/Ordering/Ordering.Infrastructure/Repositories/RequestManager.cs
  20. +2
    -0
      src/Web/WebMVC/Services/BasketService.cs
  21. +2
    -0
      src/Web/WebMVC/Services/OrderingService.cs
  22. +13
    -7
      src/Web/WebMVC/Services/Utilities/HttpApiClientWrapper.cs

+ 18
- 0
src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs View File

@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Basket.API.Infrastructure.ActionResults
{
public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object error)
: base(error)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
}
}

+ 24
- 0
src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Basket.API.Infrastructure.Exceptions
{
/// <summary>
/// Exception type for app exceptions
/// </summary>
public class BasketDomainException : Exception
{
public BasketDomainException()
{ }
public BasketDomainException(string message)
: base(message)
{ }
public BasketDomainException(string message, Exception innerException)
: base(message, innerException)
{ }
}
}

+ 67
- 0
src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs View File

@ -0,0 +1,67 @@
using Basket.API.Infrastructure.ActionResults;
using Basket.API.Infrastructure.Exceptions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Basket.API.Infrastructure.Filters
{
public class HttpGlobalExceptionFilter : IExceptionFilter
{
private readonly IHostingEnvironment env;
private readonly ILogger<HttpGlobalExceptionFilter> logger;
public HttpGlobalExceptionFilter(IHostingEnvironment env, ILogger<HttpGlobalExceptionFilter> logger)
{
this.env = env;
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult),
context.Exception,
context.Exception.Message);
if (context.Exception.GetType() == typeof(BasketDomainException))
{
var json = new JsonErrorResponse
{
Messages = new[] { context.Exception.Message }
};
context.Result = new BadRequestObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
else
{
var json = new JsonErrorResponse
{
Messages = new[] { "An error ocurr.Try it again." }
};
if (env.IsDevelopment())
{
json.DeveloperMeesage = context.Exception;
}
context.Result = new InternalServerErrorObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
context.ExceptionHandled = true;
}
private class JsonErrorResponse
{
public string[] Messages { get; set; }
public object DeveloperMeesage { get; set; }
}
}
}

+ 6
- 1
src/Services/Basket/Basket.API/Startup.cs View File

@ -14,6 +14,7 @@ using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling; using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
using System; using System;
using Basket.API.Infrastructure.Filters;
namespace Microsoft.eShopOnContainers.Services.Basket.API namespace Microsoft.eShopOnContainers.Services.Basket.API
{ {
@ -35,7 +36,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add framework services. // Add framework services.
services.AddMvc();
services.AddMvc(options =>
{
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
}).AddControllersAsServices();
services.Configure<BasketSettings>(Configuration); services.Configure<BasketSettings>(Configuration);
//By connecting here we are making sure that our service //By connecting here we are making sure that our service


+ 18
- 0
src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs View File

@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Catalog.API.Infrastructure.ActionResults
{
public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object error)
: base(error)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
}
}

+ 24
- 0
src/Services/Catalog/Catalog.API/Infrastructure/Exceptions/CatalogDomainException.cs View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Catalog.API.Infrastructure.Exceptions
{
/// <summary>
/// Exception type for app exceptions
/// </summary>
public class CatalogDomainException : Exception
{
public CatalogDomainException()
{ }
public CatalogDomainException(string message)
: base(message)
{ }
public CatalogDomainException(string message, Exception innerException)
: base(message, innerException)
{ }
}
}

+ 63
- 0
src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs View File

@ -0,0 +1,63 @@
using Catalog.API.Infrastructure.ActionResults;
using Catalog.API.Infrastructure.Exceptions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Net;
namespace Catalog.API.Infrastructure.Filters
{
public class HttpGlobalExceptionFilter : IExceptionFilter
{
private readonly IHostingEnvironment env;
private readonly ILogger<HttpGlobalExceptionFilter> logger;
public HttpGlobalExceptionFilter(IHostingEnvironment env, ILogger<HttpGlobalExceptionFilter> logger)
{
this.env = env;
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult),
context.Exception,
context.Exception.Message);
if (context.Exception.GetType() == typeof(CatalogDomainException))
{
var json = new JsonErrorResponse
{
Messages = new[] { context.Exception.Message }
};
context.Result = new BadRequestObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
else
{
var json = new JsonErrorResponse
{
Messages = new[] { "An error ocurr.Try it again." }
};
if (env.IsDevelopment())
{
json.DeveloperMeesage = context.Exception;
}
context.Result = new InternalServerErrorObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
context.ExceptionHandled = true;
}
private class JsonErrorResponse
{
public string[] Messages { get; set; }
public object DeveloperMeesage { get; set; }
}
}
}

+ 8
- 9
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -1,5 +1,6 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API namespace Microsoft.eShopOnContainers.Services.Catalog.API
{ {
using global::Catalog.API.Infrastructure.Filters;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -15,7 +16,6 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Data.Common; using System.Data.Common;
using System.Data.SqlClient;
using System.Reflection; using System.Reflection;
public class Startup public class Startup
@ -41,6 +41,12 @@
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add framework services.
services.AddMvc(options =>
{
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
}).AddControllersAsServices();
services.AddDbContext<CatalogContext>(options => services.AddDbContext<CatalogContext>(options =>
{ {
options.UseSqlServer(Configuration["ConnectionString"], options.UseSqlServer(Configuration["ConnectionString"],
@ -86,20 +92,13 @@
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
var configuration = serviceProvider.GetRequiredService<IOptionsSnapshot<Settings>>().Value; var configuration = serviceProvider.GetRequiredService<IOptionsSnapshot<Settings>>().Value;
services.AddSingleton<IEventBus>(new EventBusRabbitMQ(configuration.EventBusConnection));
services.AddMvc();
services.AddSingleton<IEventBus>(new EventBusRabbitMQ(configuration.EventBusConnection));
} }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ {
//Configure logs //Configure logs
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); loggerFactory.AddDebug();


+ 1
- 4
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs View File

@ -51,11 +51,8 @@
_orderRepository.Add(order); _orderRepository.Add(order);
var result = await _orderRepository.UnitOfWork
return await _orderRepository.UnitOfWork
.SaveEntitiesAsync(); .SaveEntitiesAsync();
return result > 0;
} }
} }
} }

+ 2
- 2
src/Services/Ordering/Ordering.API/Application/Commands/IdentifierCommandHandler.cs View File

@ -48,9 +48,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
return CreateResultForDuplicateRequest(); return CreateResultForDuplicateRequest();
} }
else else
{
await _requestManager.CreateRequestForCommandAsync<T>(message.Id);
{
var result = await _mediator.SendAsync(message.Command); var result = await _mediator.SendAsync(message.Command);
await _requestManager.CreateRequestForCommandAsync<T>(message.Id);
return result; return result;
} }
} }


+ 6
- 3
src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs View File

@ -1,11 +1,12 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters
{ {
using AspNetCore.Mvc; using AspNetCore.Mvc;
using global::Ordering.Domain.Exceptions;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults; using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System;
using System.Net;
public class HttpGlobalExceptionFilter : IExceptionFilter public class HttpGlobalExceptionFilter : IExceptionFilter
{ {
@ -24,7 +25,7 @@
context.Exception, context.Exception,
context.Exception.Message); context.Exception.Message);
if (context.Exception.GetType() == typeof(ArgumentException)) //TODO:Select a common exception for application like EshopException
if (context.Exception.GetType() == typeof(OrderingDomainException))
{ {
var json = new JsonErrorResponse var json = new JsonErrorResponse
{ {
@ -32,6 +33,7 @@
}; };
context.Result = new BadRequestObjectResult(json); context.Result = new BadRequestObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
} }
else else
{ {
@ -46,8 +48,9 @@
} }
context.Result = new InternalServerErrorObjectResult(json); context.Result = new InternalServerErrorObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
} }
context.ExceptionHandled = true;
} }
private class JsonErrorResponse private class JsonErrorResponse


+ 2
- 7
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -45,7 +45,7 @@
// Add framework services. // Add framework services.
services.AddMvc(options => services.AddMvc(options =>
{ {
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
}).AddControllersAsServices(); //Injecting Controllers themselves thru DI }).AddControllersAsServices(); //Injecting Controllers themselves thru DI
//For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services //For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services
@ -106,12 +106,7 @@
{ {
loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("CorsPolicy"); app.UseCors("CorsPolicy");
app.UseFailingMiddleware(); app.UseFailingMiddleware();


+ 5
- 4
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs View File

@ -1,4 +1,5 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork; using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using Ordering.Domain.Exceptions;
using System; using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
@ -22,13 +23,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
public PaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration) public PaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)
{ {
_cardNumber = !string.IsNullOrWhiteSpace(cardNumber) ? cardNumber : throw new ArgumentException(nameof(cardNumber));
_securityNumber = !string.IsNullOrWhiteSpace(securityNumber) ? securityNumber : throw new ArgumentException(nameof(securityNumber));
_cardHolderName = !string.IsNullOrWhiteSpace(cardHolderName) ? cardHolderName : throw new ArgumentException(nameof(cardHolderName));
_cardNumber = !string.IsNullOrWhiteSpace(cardNumber) ? cardNumber : throw new OrderingDomainException(nameof(cardNumber));
_securityNumber = !string.IsNullOrWhiteSpace(securityNumber) ? securityNumber : throw new OrderingDomainException(nameof(securityNumber));
_cardHolderName = !string.IsNullOrWhiteSpace(cardHolderName) ? cardHolderName : throw new OrderingDomainException(nameof(cardHolderName));
if (expiration < DateTime.UtcNow) if (expiration < DateTime.UtcNow)
{ {
throw new ArgumentException(nameof(expiration));
throw new OrderingDomainException(nameof(expiration));
} }
_alias = alias; _alias = alias;


+ 5
- 4
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs View File

@ -1,4 +1,5 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork; using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using Ordering.Domain.Exceptions;
using System; using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
@ -24,12 +25,12 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{ {
if (units <= 0) if (units <= 0)
{ {
throw new ArgumentNullException("Invalid number of units");
throw new OrderingDomainException("Invalid number of units");
} }
if ((unitPrice * units) < discount) if ((unitPrice * units) < discount)
{ {
throw new ArgumentException("The total of order item is lower than applied discount");
throw new OrderingDomainException("The total of order item is lower than applied discount");
} }
ProductId = productId; ProductId = productId;
@ -58,7 +59,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{ {
if (discount < 0) if (discount < 0)
{ {
throw new ArgumentException("Discount is not valid");
throw new OrderingDomainException("Discount is not valid");
} }
_discount = discount; _discount = discount;
@ -68,7 +69,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{ {
if (units < 0) if (units < 0)
{ {
throw new ArgumentException("Invalid units");
throw new OrderingDomainException("Invalid units");
} }
_units += units; _units += units;


+ 3
- 2
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs View File

@ -1,5 +1,6 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
{ {
using global::Ordering.Domain.Exceptions;
using Seedwork; using Seedwork;
using SeedWork; using SeedWork;
using System; using System;
@ -34,7 +35,7 @@
if (state == null) if (state == null)
{ {
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
throw new OrderingDomainException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
} }
return state; return state;
@ -46,7 +47,7 @@
if (state == null) if (state == null)
{ {
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
throw new OrderingDomainException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
} }
return state; return state;


+ 23
- 0
src/Services/Ordering/Ordering.Domain/Exceptions/OrderingDomainException.cs View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ordering.Domain.Exceptions
{
/// <summary>
/// Exception type for domain exceptions
/// </summary>
public class OrderingDomainException : Exception
{
public OrderingDomainException()
{ }
public OrderingDomainException(string message)
: base(message)
{ }
public OrderingDomainException(string message, Exception innerException)
: base(message, innerException)
{ }
}
}

+ 1
- 1
src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs View File

@ -7,6 +7,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
public interface IUnitOfWork : IDisposable public interface IUnitOfWork : IDisposable
{ {
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
Task<int> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken));
Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken));
} }
} }

+ 2
- 2
src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs View File

@ -235,7 +235,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
.IsRequired(); .IsRequired();
} }
public async Task<int> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))
public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))
{ {
// Dispatch Domain Events collection. // Dispatch Domain Events collection.
// Choices: // Choices:
@ -250,7 +250,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
// performed thought the DbContext will be commited // performed thought the DbContext will be commited
var result = await base.SaveChangesAsync(); var result = await base.SaveChangesAsync();
return result;
return true;
} }
} }
} }

+ 2
- 1
src/Services/Ordering/Ordering.Infrastructure/Repositories/RequestManager.cs View File

@ -1,4 +1,5 @@
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using Ordering.Domain.Exceptions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -26,7 +27,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
var exists = await ExistAsync(id); var exists = await ExistAsync(id);
var request = exists ? var request = exists ?
throw new Exception($"Request with {id} already exists") :
throw new OrderingDomainException($"Request with {id} already exists") :
new ClientRequest() new ClientRequest()
{ {
Id = id, Id = id,


+ 2
- 0
src/Web/WebMVC/Services/BasketService.cs View File

@ -56,6 +56,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var response = await _apiClient.PostAsync(basketUrl, basket); var response = await _apiClient.PostAsync(basketUrl, basket);
response.EnsureSuccessStatusCode();
return basket; return basket;
} }


+ 2
- 0
src/Web/WebMVC/Services/OrderingService.cs View File

@ -88,6 +88,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
throw new Exception("Error creating order, try later"); throw new Exception("Error creating order, try later");
response.EnsureSuccessStatusCode();
} }
public void OverrideUserInfoIntoOrder(Order original, Order destination) public void OverrideUserInfoIntoOrder(Order original, Order destination)


+ 13
- 7
src/Web/WebMVC/Services/Utilities/HttpApiClientWrapper.cs View File

@ -1,8 +1,10 @@
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Polly; using Polly;
using Polly.Wrap; using Polly.Wrap;
using System; using System;
using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -76,13 +78,17 @@ namespace WebMVC.Services.Utilities
// a new StringContent must be created for each retry // a new StringContent must be created for each retry
// as it is disposed after each call // as it is disposed after each call
HttpInvoker(() => HttpInvoker(() =>
{
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
// raise exception if HttpResponseCode 500
// needed for circuit breaker to track fails
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
{ {
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
// raise exception if not success response
// needed for circuit breaker to track fails
response.Result.EnsureSuccessStatusCode();
return response;
});
throw new HttpRequestException();
}
return response;
});
public Task<HttpResponseMessage> DeleteAsync(string uri) => public Task<HttpResponseMessage> DeleteAsync(string uri) =>
HttpInvoker(() => _client.DeleteAsync(uri)); HttpInvoker(() => _client.DeleteAsync(uri));


Loading…
Cancel
Save