refactor exception handler

This commit is contained in:
meysamhadeli 2022-05-26 00:27:57 +04:30
parent ccb7ffa035
commit e2a03daf46
22 changed files with 140 additions and 154 deletions

View File

@ -1,6 +1,5 @@
using BuildingBlocks.Jwt; using BuildingBlocks.Jwt;
using BuildingBlocks.Logging; using BuildingBlocks.Logging;
using BuildingBlocks.Utils;
using BuildingBlocks.Web; using BuildingBlocks.Web;
using Figgle; using Figgle;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;

View File

@ -2,14 +2,10 @@
"AppOptions": { "AppOptions": {
"Name": "ApiGateway" "Name": "ApiGateway"
}, },
"Serilog": { "LogOptions": {
"MinimumLevel": { "Level": "Information",
"Default": "Information", "LogTemplate": "{Timestamp:HH:mm:ss} [{Level:u4}] {Message:lj}{NewLine}{Exception}",
"Override": { "ElasticUri": "http://localhost:9200"
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}, },
"Yarp": { "Yarp": {
"routes": { "routes": {

View File

@ -5,7 +5,7 @@ namespace BuildingBlocks.Exception;
public class AppException : CustomException 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)
{ {
} }
} }

View File

@ -4,7 +4,7 @@ namespace BuildingBlocks.Exception
{ {
public class BadRequestException : CustomException 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)
{ {
} }

View File

@ -2,7 +2,7 @@ namespace BuildingBlocks.Exception
{ {
public class ConflictException : CustomException 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)
{ {
} }
} }

View File

@ -7,7 +7,7 @@ public class CustomException : System.Exception
public CustomException( public CustomException(
string message, string message,
HttpStatusCode statusCode = HttpStatusCode.BadRequest, HttpStatusCode statusCode = HttpStatusCode.BadRequest,
string code = null) : base(message) int? code = null) : base(message)
{ {
StatusCode = statusCode; StatusCode = statusCode;
Code = code; Code = code;
@ -17,7 +17,7 @@ public class CustomException : System.Exception
string message, string message,
System.Exception innerException, System.Exception innerException,
HttpStatusCode statusCode = HttpStatusCode.BadRequest, HttpStatusCode statusCode = HttpStatusCode.BadRequest,
string code = null) : base(message, innerException) int? code = null) : base(message, innerException)
{ {
StatusCode = statusCode; StatusCode = statusCode;
Code = code; Code = code;
@ -25,7 +25,7 @@ public class CustomException : System.Exception
public CustomException( public CustomException(
HttpStatusCode statusCode = HttpStatusCode.BadRequest, HttpStatusCode statusCode = HttpStatusCode.BadRequest,
string code = null) : base() int? code = null) : base()
{ {
StatusCode = statusCode; StatusCode = statusCode;
Code = code; Code = code;
@ -33,5 +33,5 @@ public class CustomException : System.Exception
public HttpStatusCode StatusCode { get; } public HttpStatusCode StatusCode { get; }
public string Code { get; } public int? Code { get; }
} }

View File

@ -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)
{
}
}

View File

@ -8,9 +8,9 @@ namespace BuildingBlocks.Exception
{ {
public InternalServerException() : base() { } 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)) : base(message:String.Format(CultureInfo.CurrentCulture, message, args, HttpStatusCode.InternalServerError, code))
{ {
} }

View File

@ -2,7 +2,7 @@ namespace BuildingBlocks.Exception
{ {
public class NotFoundException : CustomException 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)
{ {
} }
} }

View File

@ -1,8 +1,10 @@
using Microsoft.AspNetCore.Mvc; using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace BuildingBlocks.Exception; namespace BuildingBlocks.Exception;
public class ProblemDetailsWithCode : ProblemDetails public class ProblemDetailsWithCode : ProblemDetails
{ {
public string Code { get; set; } [JsonPropertyName("code")]
public int? Code { get; set; }
} }

View File

@ -4,11 +4,8 @@ namespace BuildingBlocks.Exception
{ {
public class ValidationException : CustomException 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; }
} }
} }

View File

@ -1,7 +1,5 @@
using BuildingBlocks.Exception; using BuildingBlocks.Exception;
using FluentValidation; using FluentValidation;
using FluentValidation.Results;
using ValidationException = BuildingBlocks.Exception.ValidationException;
namespace BuildingBlocks.Validation namespace BuildingBlocks.Validation
{ {
@ -15,7 +13,7 @@ namespace BuildingBlocks.Validation
var validationResult = await validator.ValidateAsync(request); var validationResult = await validator.ValidateAsync(request);
if (!validationResult.IsValid) if (!validationResult.IsValid)
{ {
throw new BadRequestException(validationResult.Errors.FirstOrDefault()?.ErrorMessage); throw new Exception.ValidationException(validationResult.Errors?.First()?.ErrorMessage);
} }
} }
} }

View File

@ -8,21 +8,14 @@ namespace BuildingBlocks.Validation
{ {
public class ValidationResultModel 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 string Message { get; set; } = "Validation Failed.";
public List<ValidationError> Errors { get; } public List<ValidationFailure> Errors { get; set; }
public ValidationResultModel(ValidationResult validationResult = null)
{
Errors = validationResult.Errors
.Select(error => new ValidationError(error.PropertyName, error.ErrorMessage))
.ToList();
}
public override string ToString() public override string ToString()
{ {
return JsonSerializer.Serialize(this); return JsonSerializer.Serialize(this);
} }
} }
} }

View File

@ -4,7 +4,7 @@ namespace Booking.Booking.Exceptions;
public class BookingAlreadyExistException : ConflictException public class BookingAlreadyExistException : ConflictException
{ {
public BookingAlreadyExistException(string code = default) : base("Booking already exist!", code) public BookingAlreadyExistException(int? code = default) : base("Booking already exist!", code)
{ {
} }
} }

View File

@ -22,56 +22,49 @@ public static class ProblemDetailsExtensions
var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>(); var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>();
return env.IsDevelopment() || env.IsStaging(); return env.IsDevelopment() || env.IsStaging();
}; };
x.Map<ConflictException>(ex => new ProblemDetails x.Map<ConflictException>(ex => new ProblemDetailsWithCode
{ {
Title = "Application rule broken", Title = "Application rule broken",
Status = StatusCodes.Status409Conflict, Status = StatusCodes.Status409Conflict,
Detail = ex.Message, 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 // Exception will produce and returns from our FluentValidation RequestValidationBehavior
x.Map<ValidationException>(ex => new ProblemDetails x.Map<ValidationException>(ex => new ProblemDetailsWithCode
{ {
Title = "input validation rules broken", Title = "input validation rules broken",
Status = StatusCodes.Status400BadRequest, Status = (int)ex.StatusCode,
Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), Detail = ex.Message,
Type = "https://somedomain/input-validation-rules-error" Type = "https://somedomain/input-validation-rules-error",
}); });
x.Map<BadRequestException>(ex => new ProblemDetails x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
{ {
Title = "bad request exception", Title = "bad request exception",
Status = StatusCodes.Status400BadRequest, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/bad-request-error" Type = "https://somedomain/bad-request-error",
}); });
x.Map<NotFoundException>(ex => new ProblemDetails x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
{ {
Title = "not found exception", Title = "not found exception",
Status = StatusCodes.Status404NotFound, Status = StatusCodes.Status404NotFound,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/not-found-error" Type = "https://somedomain/not-found-error",
}); });
x.Map<InternalServerException>(ex => new ProblemDetails x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
{ {
Title = "api server exception", Title = "api server exception",
Status = StatusCodes.Status400BadRequest,
Detail = ex.Message,
Type = "https://somedomain/api-server-error"
});
x.Map<AppException>(ex => new ProblemDetails
{
Title = "application exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status500InternalServerError,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/application-error" Type = "https://somedomain/api-server-error",
}); });
x.Map<IdentityException>(ex => new ProblemDetails x.Map<AppException>(ex => new ProblemDetailsWithCode
{ {
Status = (int)ex.StatusCode, Title = "application exception",
Title = "identity exception", Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/identity-error" Type = "https://somedomain/application-error",
}); });
x.Map<RpcException>(ex => new ProblemDetails x.Map<RpcException>(ex => new ProblemDetails
@ -83,6 +76,22 @@ public static class ProblemDetailsExtensions
}); });
x.MapToStatusCode<ArgumentNullException>(StatusCodes.Status400BadRequest); x.MapToStatusCode<ArgumentNullException>(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; return services;
} }

View File

@ -4,7 +4,7 @@ namespace Flight.Airports.Exceptions;
public class AirportAlreadyExistException : ConflictException public class AirportAlreadyExistException : ConflictException
{ {
public AirportAlreadyExistException(string code = default) : base("Airport already exist!", code) public AirportAlreadyExistException(int? code = default) : base("Airport already exist!", code)
{ {
} }
} }

View File

@ -2,10 +2,8 @@ using System;
using BuildingBlocks.Exception; using BuildingBlocks.Exception;
using Hellang.Middleware.ProblemDetails; using Hellang.Middleware.ProblemDetails;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
namespace Flight.Extensions; namespace Flight.Extensions;
@ -27,64 +25,63 @@ public static class ProblemDetailsExtensions
Title = "Application rule broken", Title = "Application rule broken",
Status = StatusCodes.Status409Conflict, Status = StatusCodes.Status409Conflict,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/application-rule-validation-error", Type = "https://somedomain/application-rule-validation-error"
Code = ex.Code
}); });
// Exception will produce and returns from our FluentValidation RequestValidationBehavior // Exception will produce and returns from our FluentValidation RequestValidationBehavior
x.Map<ValidationException>(ex => new ProblemDetailsWithCode x.Map<ValidationException>(ex => new ProblemDetailsWithCode
{ {
Title = "input validation rules broken", Title = "input validation rules broken",
Status = StatusCodes.Status400BadRequest, Status = (int)ex.StatusCode,
Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), Detail = ex.Message,
Type = "https://somedomain/input-validation-rules-error", Type = "https://somedomain/input-validation-rules-error"
Code = ex.Code
}); });
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
{ {
Title = "bad request exception", Title = "bad request exception",
Status = StatusCodes.Status400BadRequest, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/bad-request-error", Type = "https://somedomain/bad-request-error"
Code = ex.Code
}); });
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
{ {
Title = "not found exception", Title = "not found exception",
Status = StatusCodes.Status404NotFound, Status = StatusCodes.Status404NotFound,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/not-found-error", Type = "https://somedomain/not-found-error"
Code = ex.Code
}); });
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
{ {
Title = "api server exception", Title = "api server exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status500InternalServerError,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/api-server-error", Type = "https://somedomain/api-server-error"
Code = ex.Code
}); });
x.Map<AppException>(ex => new ProblemDetailsWithCode x.Map<AppException>(ex => new ProblemDetailsWithCode
{ {
Title = "application exception", Title = "application exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/application-error", Type = "https://somedomain/application-error"
Code = ex.Code
});
x.Map<IdentityException>(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;
}); });
x.MapToStatusCode<ArgumentNullException>(StatusCodes.Status400BadRequest); x.MapToStatusCode<ArgumentNullException>(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; return services;
} }

View File

@ -4,7 +4,7 @@ namespace Flight.Flights.Exceptions;
public class FlightAlreadyExistException : ConflictException public class FlightAlreadyExistException : ConflictException
{ {
public FlightAlreadyExistException(string code = default) : base("Flight already exist!", code) public FlightAlreadyExistException(int? code = default) : base("Flight already exist!", code)
{ {
} }
} }

View File

@ -4,7 +4,7 @@ namespace Flight.Seats.Exceptions;
public class SeatAlreadyChosenException : ConflictException public class SeatAlreadyChosenException : ConflictException
{ {
public SeatAlreadyChosenException(string code = default) : base("Seat already chosen!", code) public SeatAlreadyChosenException(int? code = default) : base("Seat already chosen!", code)
{ {
} }
} }

View File

@ -4,7 +4,7 @@ namespace Flight.Seats.Exceptions;
public class SeatAlreadyExistException : ConflictException public class SeatAlreadyExistException : ConflictException
{ {
public SeatAlreadyExistException(string code = default) : base("Seat already exist!", code) public SeatAlreadyExistException(int? code = default) : base("Seat already exist!", code)
{ {
} }
} }

View File

@ -2,10 +2,8 @@ using System;
using BuildingBlocks.Exception; using BuildingBlocks.Exception;
using Hellang.Middleware.ProblemDetails; using Hellang.Middleware.ProblemDetails;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
namespace Identity.Extensions; namespace Identity.Extensions;
@ -22,7 +20,7 @@ public static class ProblemDetailsExtensions
var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>(); var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>();
return env.IsDevelopment() || env.IsStaging(); return env.IsDevelopment() || env.IsStaging();
}; };
x.Map<ConflictException>(ex => new ProblemDetails x.Map<ConflictException>(ex => new ProblemDetailsWithCode
{ {
Title = "Application rule broken", Title = "Application rule broken",
Status = StatusCodes.Status409Conflict, Status = StatusCodes.Status409Conflict,
@ -31,55 +29,60 @@ public static class ProblemDetailsExtensions
}); });
// Exception will produce and returns from our FluentValidation RequestValidationBehavior // Exception will produce and returns from our FluentValidation RequestValidationBehavior
x.Map<ValidationException>(ex => new ProblemDetails x.Map<ValidationException>(ex => new ProblemDetailsWithCode
{ {
Title = "input validation rules broken", Title = "input validation rules broken",
Status = StatusCodes.Status400BadRequest, Status = (int)ex.StatusCode,
Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), Detail = ex.Message,
Type = "https://somedomain/input-validation-rules-error" Type = "https://somedomain/input-validation-rules-error"
}); });
x.Map<BadRequestException>(ex => new ProblemDetails x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
{ {
Title = "bad request exception", Title = "bad request exception",
Status = StatusCodes.Status400BadRequest, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/bad-request-error" Type = "https://somedomain/bad-request-error"
}); });
x.Map<NotFoundException>(ex => new ProblemDetails x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
{ {
Title = "not found exception", Title = "not found exception",
Status = StatusCodes.Status404NotFound, Status = StatusCodes.Status404NotFound,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/not-found-error" Type = "https://somedomain/not-found-error"
}); });
x.Map<InternalServerException>(ex => new ProblemDetails x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
{ {
Title = "api server exception", Title = "api server exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status500InternalServerError,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/api-server-error" Type = "https://somedomain/api-server-error"
}); });
x.Map<AppException>(ex => new ProblemDetails x.Map<AppException>(ex => new ProblemDetailsWithCode
{ {
Title = "application exception", Title = "application exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/application-error" Type = "https://somedomain/application-error"
}); });
x.Map<IdentityException>(ex =>
{
var pd = new ProblemDetails
{
Status = (int)ex.StatusCode,
Title = "identity exception",
Detail = ex.Message,
Type = "https://somedomain/identity-error"
};
return pd;
});
x.MapToStatusCode<ArgumentNullException>(StatusCodes.Status400BadRequest); x.MapToStatusCode<ArgumentNullException>(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; return services;
} }
} }

View File

@ -1,10 +1,8 @@
using BuildingBlocks.Exception; using BuildingBlocks.Exception;
using Hellang.Middleware.ProblemDetails; using Hellang.Middleware.ProblemDetails;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
namespace Passenger.Extensions; namespace Passenger.Extensions;
@ -21,7 +19,7 @@ public static class ProblemDetailsExtensions
var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>(); var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>();
return env.IsDevelopment() || env.IsStaging(); return env.IsDevelopment() || env.IsStaging();
}; };
x.Map<ConflictException>(ex => new ProblemDetails x.Map<ConflictException>(ex => new ProblemDetailsWithCode
{ {
Title = "Application rule broken", Title = "Application rule broken",
Status = StatusCodes.Status409Conflict, Status = StatusCodes.Status409Conflict,
@ -30,55 +28,60 @@ public static class ProblemDetailsExtensions
}); });
// Exception will produce and returns from our FluentValidation RequestValidationBehavior // Exception will produce and returns from our FluentValidation RequestValidationBehavior
x.Map<ValidationException>(ex => new ProblemDetails x.Map<ValidationException>(ex => new ProblemDetailsWithCode
{ {
Title = "input validation rules broken", Title = "input validation rules broken",
Status = StatusCodes.Status400BadRequest, Status = (int)ex.StatusCode,
Detail = JsonConvert.SerializeObject(ex.ValidationResultModel.Errors), Detail = ex.Message,
Type = "https://somedomain/input-validation-rules-error" Type = "https://somedomain/input-validation-rules-error"
}); });
x.Map<BadRequestException>(ex => new ProblemDetails x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
{ {
Title = "bad request exception", Title = "bad request exception",
Status = StatusCodes.Status400BadRequest, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/bad-request-error" Type = "https://somedomain/bad-request-error"
}); });
x.Map<NotFoundException>(ex => new ProblemDetails x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
{ {
Title = "not found exception", Title = "not found exception",
Status = StatusCodes.Status404NotFound, Status = StatusCodes.Status404NotFound,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/not-found-error" Type = "https://somedomain/not-found-error"
}); });
x.Map<InternalServerException>(ex => new ProblemDetails x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
{ {
Title = "api server exception", Title = "api server exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status500InternalServerError,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/api-server-error" Type = "https://somedomain/api-server-error"
}); });
x.Map<AppException>(ex => new ProblemDetails x.Map<AppException>(ex => new ProblemDetailsWithCode
{ {
Title = "application exception", Title = "application exception",
Status = StatusCodes.Status500InternalServerError, Status = StatusCodes.Status400BadRequest,
Detail = ex.Message, Detail = ex.Message,
Type = "https://somedomain/application-error" Type = "https://somedomain/application-error"
}); });
x.Map<IdentityException>(ex =>
{
var pd = new ProblemDetails
{
Status = (int)ex.StatusCode,
Title = "identity exception",
Detail = ex.Message,
Type = "https://somedomain/identity-error"
};
return pd;
});
x.MapToStatusCode<ArgumentNullException>(StatusCodes.Status400BadRequest); x.MapToStatusCode<ArgumentNullException>(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; return services;
} }
} }