diff --git a/src/ApiGateway/src/Program.cs b/src/ApiGateway/src/Program.cs index 8b66c1b..ad75dfe 100644 --- a/src/ApiGateway/src/Program.cs +++ b/src/ApiGateway/src/Program.cs @@ -1,6 +1,5 @@ using BuildingBlocks.Jwt; using BuildingBlocks.Logging; -using BuildingBlocks.Utils; using BuildingBlocks.Web; using Figgle; using Microsoft.AspNetCore.Authentication; diff --git a/src/ApiGateway/src/appsettings.json b/src/ApiGateway/src/appsettings.json index 0fd1b8d..ee4339d 100644 --- a/src/ApiGateway/src/appsettings.json +++ b/src/ApiGateway/src/appsettings.json @@ -2,14 +2,10 @@ "AppOptions": { "Name": "ApiGateway" }, - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } + "LogOptions": { + "Level": "Information", + "LogTemplate": "{Timestamp:HH:mm:ss} [{Level:u4}] {Message:lj}{NewLine}{Exception}", + "ElasticUri": "http://localhost:9200" }, "Yarp": { "routes": { diff --git a/src/BuildingBlocks/Exception/AppException.cs b/src/BuildingBlocks/Exception/AppException.cs index b2a6009..08f8b8e 100644 --- a/src/BuildingBlocks/Exception/AppException.cs +++ b/src/BuildingBlocks/Exception/AppException.cs @@ -5,7 +5,7 @@ namespace BuildingBlocks.Exception; public class AppException : CustomException { - public AppException(string message, string code = null) : base(message, code: code) + public AppException(string message, int? code = null) : base(message, code: code) { } @@ -13,11 +13,11 @@ public class AppException : CustomException { } - public AppException(string message, HttpStatusCode statusCode, string code = null) : base(message, statusCode, code) + public AppException(string message, HttpStatusCode statusCode, int? code = null) : base(message, statusCode, code) { } - public AppException(string message, System.Exception innerException, string code = null) : base(message, innerException, code: code) + public AppException(string message, System.Exception innerException, int? code = null) : base(message, innerException, code: code) { } } diff --git a/src/BuildingBlocks/Exception/BadRequestException.cs b/src/BuildingBlocks/Exception/BadRequestException.cs index bf37562..7635b2f 100644 --- a/src/BuildingBlocks/Exception/BadRequestException.cs +++ b/src/BuildingBlocks/Exception/BadRequestException.cs @@ -4,7 +4,7 @@ namespace BuildingBlocks.Exception { public class BadRequestException : CustomException { - public BadRequestException(string message, string code = null) : base(message, code: code) + public BadRequestException(string message, int? code = null) : base(message, code: code) { } diff --git a/src/BuildingBlocks/Exception/ConflictException.cs b/src/BuildingBlocks/Exception/ConflictException.cs index 7da858d..4290bf2 100644 --- a/src/BuildingBlocks/Exception/ConflictException.cs +++ b/src/BuildingBlocks/Exception/ConflictException.cs @@ -2,7 +2,7 @@ namespace BuildingBlocks.Exception { public class ConflictException : CustomException { - public ConflictException(string message, string code = null) : base(message, code: code) + public ConflictException(string message, int? code = null) : base(message, code: code) { } } diff --git a/src/BuildingBlocks/Exception/CustomException.cs b/src/BuildingBlocks/Exception/CustomException.cs index 645bf50..f60284a 100644 --- a/src/BuildingBlocks/Exception/CustomException.cs +++ b/src/BuildingBlocks/Exception/CustomException.cs @@ -7,7 +7,7 @@ public class CustomException : System.Exception public CustomException( string message, HttpStatusCode statusCode = HttpStatusCode.BadRequest, - string code = null) : base(message) + int? code = null) : base(message) { StatusCode = statusCode; Code = code; @@ -17,7 +17,7 @@ public class CustomException : System.Exception string message, System.Exception innerException, HttpStatusCode statusCode = HttpStatusCode.BadRequest, - string code = null) : base(message, innerException) + int? code = null) : base(message, innerException) { StatusCode = statusCode; Code = code; @@ -25,7 +25,7 @@ public class CustomException : System.Exception public CustomException( HttpStatusCode statusCode = HttpStatusCode.BadRequest, - string code = null) : base() + int? code = null) : base() { StatusCode = statusCode; Code = code; @@ -33,5 +33,5 @@ public class CustomException : System.Exception public HttpStatusCode StatusCode { get; } - public string Code { get; } + public int? Code { get; } } diff --git a/src/BuildingBlocks/Exception/IdentityException.cs b/src/BuildingBlocks/Exception/IdentityException.cs deleted file mode 100644 index 65a9bb0..0000000 --- a/src/BuildingBlocks/Exception/IdentityException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Net; - -namespace BuildingBlocks.Exception; - -public class IdentityException : CustomException -{ - public IdentityException(string message = default, HttpStatusCode statusCode = default, string code = null) - : base(message, statusCode, code) - { - } -} diff --git a/src/BuildingBlocks/Exception/InternalServerException.cs b/src/BuildingBlocks/Exception/InternalServerException.cs index c370c8c..d917560 100644 --- a/src/BuildingBlocks/Exception/InternalServerException.cs +++ b/src/BuildingBlocks/Exception/InternalServerException.cs @@ -8,9 +8,9 @@ namespace BuildingBlocks.Exception { public InternalServerException() : base() { } - public InternalServerException(string message, string code) : base(message, HttpStatusCode.InternalServerError, code: code) { } + public InternalServerException(string message, int? code) : base(message, HttpStatusCode.InternalServerError, code: code) { } - public InternalServerException(string message, string code = null, params object[] args) + public InternalServerException(string message, int? code = null, params object[] args) : base(message:String.Format(CultureInfo.CurrentCulture, message, args, HttpStatusCode.InternalServerError, code)) { } diff --git a/src/BuildingBlocks/Exception/NotFoundException.cs b/src/BuildingBlocks/Exception/NotFoundException.cs index 86bb198..daae1b9 100644 --- a/src/BuildingBlocks/Exception/NotFoundException.cs +++ b/src/BuildingBlocks/Exception/NotFoundException.cs @@ -2,7 +2,7 @@ namespace BuildingBlocks.Exception { public class NotFoundException : CustomException { - public NotFoundException(string message, string code = null) : base(message, code: code) + public NotFoundException(string message, int? code = null) : base(message, code: code) { } } diff --git a/src/BuildingBlocks/Exception/ProblemDetailsWithCode.cs b/src/BuildingBlocks/Exception/ProblemDetailsWithCode.cs index 841c5ad..2832cad 100644 --- a/src/BuildingBlocks/Exception/ProblemDetailsWithCode.cs +++ b/src/BuildingBlocks/Exception/ProblemDetailsWithCode.cs @@ -1,8 +1,10 @@ -using Microsoft.AspNetCore.Mvc; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc; namespace BuildingBlocks.Exception; public class ProblemDetailsWithCode : ProblemDetails { - public string Code { get; set; } + [JsonPropertyName("code")] + public int? Code { get; set; } } diff --git a/src/BuildingBlocks/Exception/ValidationException.cs b/src/BuildingBlocks/Exception/ValidationException.cs index b7f7c6a..4847d0b 100644 --- a/src/BuildingBlocks/Exception/ValidationException.cs +++ b/src/BuildingBlocks/Exception/ValidationException.cs @@ -4,11 +4,8 @@ namespace BuildingBlocks.Exception { public class ValidationException : CustomException { - public ValidationException(ValidationResultModel validationResultModel) + public ValidationException(string message, int? code = null) : base(message, code: code) { - ValidationResultModel = validationResultModel; } - - public ValidationResultModel ValidationResultModel { get; } } } diff --git a/src/BuildingBlocks/Validation/Extensions.cs b/src/BuildingBlocks/Validation/Extensions.cs index 522742d..c6971f8 100644 --- a/src/BuildingBlocks/Validation/Extensions.cs +++ b/src/BuildingBlocks/Validation/Extensions.cs @@ -1,7 +1,5 @@ using BuildingBlocks.Exception; using FluentValidation; -using FluentValidation.Results; -using ValidationException = BuildingBlocks.Exception.ValidationException; namespace BuildingBlocks.Validation { @@ -15,7 +13,7 @@ namespace BuildingBlocks.Validation var validationResult = await validator.ValidateAsync(request); if (!validationResult.IsValid) { - throw new BadRequestException(validationResult.Errors.FirstOrDefault()?.ErrorMessage); + throw new Exception.ValidationException(validationResult.Errors?.First()?.ErrorMessage); } } } diff --git a/src/BuildingBlocks/Validation/ValidationResultModel.cs b/src/BuildingBlocks/Validation/ValidationResultModel.cs index 03979fa..45bd2c4 100644 --- a/src/BuildingBlocks/Validation/ValidationResultModel.cs +++ b/src/BuildingBlocks/Validation/ValidationResultModel.cs @@ -8,21 +8,14 @@ namespace BuildingBlocks.Validation { public class ValidationResultModel { - public int StatusCode { get; set; } = (int) HttpStatusCode.BadRequest; + public int StatusCode { get; set; } = (int)HttpStatusCode.BadRequest; public string Message { get; set; } = "Validation Failed."; - public List Errors { get; } - - public ValidationResultModel(ValidationResult validationResult = null) - { - Errors = validationResult.Errors - .Select(error => new ValidationError(error.PropertyName, error.ErrorMessage)) - .ToList(); - } + public List Errors { get; set; } public override string ToString() { return JsonSerializer.Serialize(this); } } -} \ No newline at end of file +} diff --git a/src/Services/Booking/src/Booking/Booking/Exceptions/BookingAlreadyExistException.cs b/src/Services/Booking/src/Booking/Booking/Exceptions/BookingAlreadyExistException.cs index a577a98..f18d25c 100644 --- a/src/Services/Booking/src/Booking/Booking/Exceptions/BookingAlreadyExistException.cs +++ b/src/Services/Booking/src/Booking/Booking/Exceptions/BookingAlreadyExistException.cs @@ -4,7 +4,7 @@ namespace Booking.Booking.Exceptions; public class BookingAlreadyExistException : ConflictException { - public BookingAlreadyExistException(string code = default) : base("Booking already exist!", code) + public BookingAlreadyExistException(int? code = default) : base("Booking already exist!", code) { } } diff --git a/src/Services/Booking/src/Booking/Extensions/ProblemDetailsExtensions.cs b/src/Services/Booking/src/Booking/Extensions/ProblemDetailsExtensions.cs index bb54a74..68022aa 100644 --- a/src/Services/Booking/src/Booking/Extensions/ProblemDetailsExtensions.cs +++ b/src/Services/Booking/src/Booking/Extensions/ProblemDetailsExtensions.cs @@ -22,56 +22,49 @@ public static class ProblemDetailsExtensions var env = ctx.RequestServices.GetRequiredService(); return env.IsDevelopment() || env.IsStaging(); }; - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "Application rule broken", Status = StatusCodes.Status409Conflict, Detail = ex.Message, - Type = "https://somedomain/application-rule-validation-error" + Type = "https://somedomain/application-rule-validation-error", }); // Exception will produce and returns from our FluentValidation RequestValidationBehavior - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "input validation rules broken", - Status = StatusCodes.Status400BadRequest, - Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), - Type = "https://somedomain/input-validation-rules-error" + Status = (int)ex.StatusCode, + Detail = ex.Message, + Type = "https://somedomain/input-validation-rules-error", }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "bad request exception", Status = StatusCodes.Status400BadRequest, Detail = ex.Message, - Type = "https://somedomain/bad-request-error" + Type = "https://somedomain/bad-request-error", }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "not found exception", Status = StatusCodes.Status404NotFound, Detail = ex.Message, - Type = "https://somedomain/not-found-error" + Type = "https://somedomain/not-found-error", }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "api server exception", - Status = StatusCodes.Status400BadRequest, - Detail = ex.Message, - Type = "https://somedomain/api-server-error" - }); - x.Map(ex => new ProblemDetails - { - Title = "application exception", Status = StatusCodes.Status500InternalServerError, Detail = ex.Message, - Type = "https://somedomain/application-error" + Type = "https://somedomain/api-server-error", }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { - Status = (int)ex.StatusCode, - Title = "identity exception", + Title = "application exception", + Status = StatusCodes.Status400BadRequest, Detail = ex.Message, - Type = "https://somedomain/identity-error" + Type = "https://somedomain/application-error", }); x.Map(ex => new ProblemDetails @@ -83,6 +76,22 @@ public static class ProblemDetailsExtensions }); x.MapToStatusCode(StatusCodes.Status400BadRequest); + + x.MapStatusCode = context => + { + return context.Response.StatusCode switch + { + StatusCodes.Status401Unauthorized => new ProblemDetailsWithCode + { + Status = context.Response.StatusCode, + Title = "identity exception", + Detail = "You are not Authorized", + Type = "https://somedomain/identity-error", + }, + + _ => new StatusCodeProblemDetails(context.Response.StatusCode) + }; + }; }); return services; } diff --git a/src/Services/Flight/src/Flight/Airports/Exceptions/AirportAlreadyExistException.cs b/src/Services/Flight/src/Flight/Airports/Exceptions/AirportAlreadyExistException.cs index cdd8874..e850127 100644 --- a/src/Services/Flight/src/Flight/Airports/Exceptions/AirportAlreadyExistException.cs +++ b/src/Services/Flight/src/Flight/Airports/Exceptions/AirportAlreadyExistException.cs @@ -4,7 +4,7 @@ namespace Flight.Airports.Exceptions; public class AirportAlreadyExistException : ConflictException { - public AirportAlreadyExistException(string code = default) : base("Airport already exist!", code) + public AirportAlreadyExistException(int? code = default) : base("Airport already exist!", code) { } } diff --git a/src/Services/Flight/src/Flight/Extensions/ProblemDetailsExtensions.cs b/src/Services/Flight/src/Flight/Extensions/ProblemDetailsExtensions.cs index 47cc909..dab81e8 100644 --- a/src/Services/Flight/src/Flight/Extensions/ProblemDetailsExtensions.cs +++ b/src/Services/Flight/src/Flight/Extensions/ProblemDetailsExtensions.cs @@ -2,10 +2,8 @@ using System; using BuildingBlocks.Exception; using Hellang.Middleware.ProblemDetails; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; namespace Flight.Extensions; @@ -27,64 +25,63 @@ public static class ProblemDetailsExtensions Title = "Application rule broken", Status = StatusCodes.Status409Conflict, Detail = ex.Message, - Type = "https://somedomain/application-rule-validation-error", - Code = ex.Code + Type = "https://somedomain/application-rule-validation-error" }); // Exception will produce and returns from our FluentValidation RequestValidationBehavior x.Map(ex => new ProblemDetailsWithCode { Title = "input validation rules broken", - Status = StatusCodes.Status400BadRequest, - Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), - Type = "https://somedomain/input-validation-rules-error", - Code = ex.Code + Status = (int)ex.StatusCode, + Detail = ex.Message, + Type = "https://somedomain/input-validation-rules-error" }); x.Map(ex => new ProblemDetailsWithCode { Title = "bad request exception", Status = StatusCodes.Status400BadRequest, Detail = ex.Message, - Type = "https://somedomain/bad-request-error", - Code = ex.Code + Type = "https://somedomain/bad-request-error" }); x.Map(ex => new ProblemDetailsWithCode { Title = "not found exception", Status = StatusCodes.Status404NotFound, Detail = ex.Message, - Type = "https://somedomain/not-found-error", - Code = ex.Code + Type = "https://somedomain/not-found-error" }); x.Map(ex => new ProblemDetailsWithCode { Title = "api server exception", Status = StatusCodes.Status500InternalServerError, Detail = ex.Message, - Type = "https://somedomain/api-server-error", - Code = ex.Code + Type = "https://somedomain/api-server-error" }); x.Map(ex => new ProblemDetailsWithCode { Title = "application exception", - Status = StatusCodes.Status500InternalServerError, + Status = StatusCodes.Status400BadRequest, Detail = ex.Message, - Type = "https://somedomain/application-error", - Code = ex.Code - }); - x.Map(ex => - { - var pd = new ProblemDetailsWithCode - { - Status = (int)ex.StatusCode, - Title = "identity exception", - Detail = ex.Message, - Type = "https://somedomain/identity-error", - Code = ex.Code - }; - return pd; + Type = "https://somedomain/application-error" }); + x.MapToStatusCode(StatusCodes.Status400BadRequest); + + x.MapStatusCode = context => + { + return context.Response.StatusCode switch + { + StatusCodes.Status401Unauthorized => new ProblemDetailsWithCode + { + Status = context.Response.StatusCode, + Title = "identity exception", + Detail = "You are not Authorized", + Type = "https://somedomain/identity-error" + }, + + _ => new StatusCodeProblemDetails(context.Response.StatusCode) + }; + }; }); return services; } diff --git a/src/Services/Flight/src/Flight/Flights/Exceptions/FlightAlreadyExistException.cs b/src/Services/Flight/src/Flight/Flights/Exceptions/FlightAlreadyExistException.cs index dc39b3d..be1740e 100644 --- a/src/Services/Flight/src/Flight/Flights/Exceptions/FlightAlreadyExistException.cs +++ b/src/Services/Flight/src/Flight/Flights/Exceptions/FlightAlreadyExistException.cs @@ -4,7 +4,7 @@ namespace Flight.Flights.Exceptions; public class FlightAlreadyExistException : ConflictException { - public FlightAlreadyExistException(string code = default) : base("Flight already exist!", code) + public FlightAlreadyExistException(int? code = default) : base("Flight already exist!", code) { } } diff --git a/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyChosenException.cs b/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyChosenException.cs index 4ddcff5..5c132c2 100644 --- a/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyChosenException.cs +++ b/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyChosenException.cs @@ -4,7 +4,7 @@ namespace Flight.Seats.Exceptions; public class SeatAlreadyChosenException : ConflictException { - public SeatAlreadyChosenException(string code = default) : base("Seat already chosen!", code) + public SeatAlreadyChosenException(int? code = default) : base("Seat already chosen!", code) { } } diff --git a/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyExistException.cs b/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyExistException.cs index 730df1c..35c59b1 100644 --- a/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyExistException.cs +++ b/src/Services/Flight/src/Flight/Seats/Exceptions/SeatAlreadyExistException.cs @@ -4,7 +4,7 @@ namespace Flight.Seats.Exceptions; public class SeatAlreadyExistException : ConflictException { - public SeatAlreadyExistException(string code = default) : base("Seat already exist!", code) + public SeatAlreadyExistException(int? code = default) : base("Seat already exist!", code) { } } diff --git a/src/Services/Identity/src/Identity/Extensions/ProblemDetailsExtensions.cs b/src/Services/Identity/src/Identity/Extensions/ProblemDetailsExtensions.cs index 7bb8e50..2455b6e 100644 --- a/src/Services/Identity/src/Identity/Extensions/ProblemDetailsExtensions.cs +++ b/src/Services/Identity/src/Identity/Extensions/ProblemDetailsExtensions.cs @@ -2,10 +2,8 @@ using System; using BuildingBlocks.Exception; using Hellang.Middleware.ProblemDetails; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; namespace Identity.Extensions; @@ -22,7 +20,7 @@ public static class ProblemDetailsExtensions var env = ctx.RequestServices.GetRequiredService(); return env.IsDevelopment() || env.IsStaging(); }; - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "Application rule broken", Status = StatusCodes.Status409Conflict, @@ -31,55 +29,60 @@ public static class ProblemDetailsExtensions }); // Exception will produce and returns from our FluentValidation RequestValidationBehavior - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "input validation rules broken", - Status = StatusCodes.Status400BadRequest, - Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), + Status = (int)ex.StatusCode, + Detail = ex.Message, Type = "https://somedomain/input-validation-rules-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "bad request exception", Status = StatusCodes.Status400BadRequest, Detail = ex.Message, Type = "https://somedomain/bad-request-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "not found exception", Status = StatusCodes.Status404NotFound, Detail = ex.Message, Type = "https://somedomain/not-found-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "api server exception", Status = StatusCodes.Status500InternalServerError, Detail = ex.Message, Type = "https://somedomain/api-server-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "application exception", - Status = StatusCodes.Status500InternalServerError, + Status = StatusCodes.Status400BadRequest, Detail = ex.Message, Type = "https://somedomain/application-error" }); - x.Map(ex => - { - var pd = new ProblemDetails - { - Status = (int)ex.StatusCode, - Title = "identity exception", - Detail = ex.Message, - Type = "https://somedomain/identity-error" - }; - return pd; - }); x.MapToStatusCode(StatusCodes.Status400BadRequest); + + x.MapStatusCode = context => + { + return context.Response.StatusCode switch + { + StatusCodes.Status401Unauthorized => new ProblemDetailsWithCode + { + Status = context.Response.StatusCode, + Title = "identity exception", + Detail = "You are not Authorized", + Type = "https://somedomain/identity-error" + }, + + _ => new StatusCodeProblemDetails(context.Response.StatusCode) + }; + }; }); return services; } -} \ No newline at end of file +} diff --git a/src/Services/Passenger/src/Passenger/Extensions/ProblemDetailsExtensions.cs b/src/Services/Passenger/src/Passenger/Extensions/ProblemDetailsExtensions.cs index 176f607..0ba16b6 100644 --- a/src/Services/Passenger/src/Passenger/Extensions/ProblemDetailsExtensions.cs +++ b/src/Services/Passenger/src/Passenger/Extensions/ProblemDetailsExtensions.cs @@ -1,10 +1,8 @@ using BuildingBlocks.Exception; using Hellang.Middleware.ProblemDetails; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; namespace Passenger.Extensions; @@ -21,7 +19,7 @@ public static class ProblemDetailsExtensions var env = ctx.RequestServices.GetRequiredService(); return env.IsDevelopment() || env.IsStaging(); }; - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "Application rule broken", Status = StatusCodes.Status409Conflict, @@ -30,55 +28,60 @@ public static class ProblemDetailsExtensions }); // Exception will produce and returns from our FluentValidation RequestValidationBehavior - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "input validation rules broken", - Status = StatusCodes.Status400BadRequest, - Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), + Status = (int)ex.StatusCode, + Detail = ex.Message, Type = "https://somedomain/input-validation-rules-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "bad request exception", Status = StatusCodes.Status400BadRequest, Detail = ex.Message, Type = "https://somedomain/bad-request-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "not found exception", Status = StatusCodes.Status404NotFound, Detail = ex.Message, Type = "https://somedomain/not-found-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "api server exception", Status = StatusCodes.Status500InternalServerError, Detail = ex.Message, Type = "https://somedomain/api-server-error" }); - x.Map(ex => new ProblemDetails + x.Map(ex => new ProblemDetailsWithCode { Title = "application exception", - Status = StatusCodes.Status500InternalServerError, + Status = StatusCodes.Status400BadRequest, Detail = ex.Message, Type = "https://somedomain/application-error" }); - x.Map(ex => - { - var pd = new ProblemDetails - { - Status = (int)ex.StatusCode, - Title = "identity exception", - Detail = ex.Message, - Type = "https://somedomain/identity-error" - }; - return pd; - }); x.MapToStatusCode(StatusCodes.Status400BadRequest); + + x.MapStatusCode = context => + { + return context.Response.StatusCode switch + { + StatusCodes.Status401Unauthorized => new ProblemDetailsWithCode + { + Status = context.Response.StatusCode, + Title = "identity exception", + Detail = "You are not Authorized", + Type = "https://somedomain/identity-error" + }, + + _ => new StatusCodeProblemDetails(context.Response.StatusCode) + }; + }; }); return services; } -} \ No newline at end of file +}