From 05fe4ccd6dd0d5e0187c952736d0ccb08933b3d8 Mon Sep 17 00:00:00 2001 From: Christian Arenas Date: Fri, 2 Jun 2017 16:31:03 +0200 Subject: [PATCH] Add exceptions filters --- .../InternalServerErrorObjectResult.cs | 14 ++++ .../Exceptions/MarketingDomainException.cs | 21 ++++++ .../Filters/HttpGlobalExceptionFilter.cs | 67 +++++++++++++++++++ .../Marketing/Marketing.API/Startup.cs | 6 +- 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/Services/Marketing/Marketing.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs create mode 100644 src/Services/Marketing/Marketing.API/Infrastructure/Exceptions/MarketingDomainException.cs create mode 100644 src/Services/Marketing/Marketing.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs b/src/Services/Marketing/Marketing.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs new file mode 100644 index 000000000..5975d92af --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs @@ -0,0 +1,14 @@ +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.ActionResults +{ + using AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + + public class InternalServerErrorObjectResult : ObjectResult + { + public InternalServerErrorObjectResult(object error) + : base(error) + { + StatusCode = StatusCodes.Status500InternalServerError; + } + } +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/Exceptions/MarketingDomainException.cs b/src/Services/Marketing/Marketing.API/Infrastructure/Exceptions/MarketingDomainException.cs new file mode 100644 index 000000000..68ccd9e52 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/Exceptions/MarketingDomainException.cs @@ -0,0 +1,21 @@ +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Exceptions +{ + using System; + + /// + /// Exception type for app exceptions + /// + public class MarketingDomainException : Exception + { + public MarketingDomainException() + { } + + public MarketingDomainException(string message) + : base(message) + { } + + public MarketingDomainException(string message, Exception innerException) + : base(message, innerException) + { } + } +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Marketing/Marketing.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs new file mode 100644 index 000000000..14e79775d --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs @@ -0,0 +1,67 @@ +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Filters +{ + using AspNetCore.Mvc; + using global::Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Exceptions; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Mvc.Filters; + using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.ActionResults; + using Microsoft.Extensions.Logging; + using System.Net; + + public class HttpGlobalExceptionFilter : IExceptionFilter + { + private readonly IHostingEnvironment env; + private readonly ILogger logger; + + public HttpGlobalExceptionFilter(IHostingEnvironment env, ILogger 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(MarketingDomainException)) + { + var json = new JsonErrorResponse + { + Messages = new[] { context.Exception.Message } + }; + + // Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1 + //It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information + context.Result = new BadRequestObjectResult(json); + context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; + } + else + { + var json = new JsonErrorResponse + { + Messages = new[] { "An error occur.Try it again." } + }; + + if (env.IsDevelopment()) + { + json.DeveloperMessage = context.Exception; + } + + // Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1 + // It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information + 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 DeveloperMessage { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 378ba214c..9609f903f 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using System.Reflection; using System; + using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Filters; public class Startup { @@ -37,7 +38,10 @@ public void ConfigureServices(IServiceCollection services) { // Add framework services. - services.AddMvc(); + services.AddMvc(options => + { + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); + }).AddControllersAsServices(); //Injecting Controllers themselves thru DIFor further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services services.AddDbContext(options => {