diff --git a/Directory.Build.props b/Directory.Build.props index 1b0caac..26a091c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 3.7.0 + 3.8.0 11.0 enable enable diff --git a/ReleaseNotes.md b/ReleaseNotes.md index fdfcc36..a46c0a1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,9 @@ # Release Notes +## 3.8.0 + +* Add `FacilityExceptionHandlerOptions.ContentSerializer`. + ## 3.7.0 * Update Facility and FacilityCSharp to add support for `datetime` fields. diff --git a/src/Facility.AspNetCore/FacilityAspNetCoreExtensions.cs b/src/Facility.AspNetCore/FacilityAspNetCoreExtensions.cs index e7f3e96..3654cb9 100644 --- a/src/Facility.AspNetCore/FacilityAspNetCoreExtensions.cs +++ b/src/Facility.AspNetCore/FacilityAspNetCoreExtensions.cs @@ -27,19 +27,32 @@ public static IApplicationBuilder UseFacilityHttpHandler(this IApplicationBui /// Adds a Facility service exception handler to the pipeline. /// /// Do not include error details in production. - public static IApplicationBuilder UseFacilityExceptionHandler(this IApplicationBuilder builder, bool includeErrorDetails = false) + public static IApplicationBuilder UseFacilityExceptionHandler(this IApplicationBuilder builder, Action? configure = null) { if (builder == null) throw new ArgumentNullException(nameof(builder)); + var options = new FacilityExceptionHandlerOptions(); + configure?.Invoke(options); + + var includeErrorDetails = options.IncludeErrorDetails; + var contentSerializer = options.ContentSerializer ?? HttpContentSerializer.Create(SystemTextJsonServiceSerializer.Instance); + return builder.UseExceptionHandler( - options => options.Run(async context => + x => x.Run(async context => { var exception = context.Features.Get()?.Error; var error = includeErrorDetails && exception != null ? ServiceErrorUtility.CreateInternalErrorForException(exception) : ServiceErrors.CreateInternalError(); - using var httpResponseMessage = FacilityAspNetCoreUtility.CreateHttpResponseMessage(error); + using var httpResponseMessage = FacilityAspNetCoreUtility.CreateHttpResponseMessage(error, contentSerializer); await FacilityAspNetCoreUtility.WriteHttpResponseMessageAsync(httpResponseMessage, context.Response); })); } + + /// + /// Adds a Facility service exception handler to the pipeline. + /// + /// Do not include error details in production. + public static IApplicationBuilder UseFacilityExceptionHandler(this IApplicationBuilder builder, bool includeErrorDetails) => + builder.UseFacilityExceptionHandler(x => x.IncludeErrorDetails = includeErrorDetails); } } diff --git a/src/Facility.AspNetCore/FacilityAspNetCoreUtility.cs b/src/Facility.AspNetCore/FacilityAspNetCoreUtility.cs index 0a72684..430a5a5 100644 --- a/src/Facility.AspNetCore/FacilityAspNetCoreUtility.cs +++ b/src/Facility.AspNetCore/FacilityAspNetCoreUtility.cs @@ -28,16 +28,21 @@ public static HttpRequestMessage CreateHttpRequestMessage(HttpRequest httpReques return httpRequestMessage; } + [Obsolete("Specify contentSerializer.")] public static HttpResponseMessage CreateHttpResponseMessage(Exception exception) => - CreateHttpResponseMessage(ServiceErrorUtility.CreateInternalErrorForException(exception)); + CreateHttpResponseMessage(exception, HttpContentSerializer.Create(SystemTextJsonServiceSerializer.Instance)); - public static HttpResponseMessage CreateHttpResponseMessage(ServiceErrorDto error) + [Obsolete("Specify contentSerializer.")] + public static HttpResponseMessage CreateHttpResponseMessage(ServiceErrorDto error) => + CreateHttpResponseMessage(error, HttpContentSerializer.Create(SystemTextJsonServiceSerializer.Instance)); + + public static HttpResponseMessage CreateHttpResponseMessage(Exception exception, HttpContentSerializer contentSerializer) => + CreateHttpResponseMessage(ServiceErrorUtility.CreateInternalErrorForException(exception), contentSerializer); + + public static HttpResponseMessage CreateHttpResponseMessage(ServiceErrorDto error, HttpContentSerializer contentSerializer) { var statusCode = HttpServiceErrors.TryGetHttpStatusCode(error.Code) ?? HttpStatusCode.InternalServerError; - return new HttpResponseMessage(statusCode) - { - Content = HttpContentSerializer.Create(SystemTextJsonServiceSerializer.Instance).CreateHttpContent(error), - }; + return new HttpResponseMessage(statusCode) { Content = contentSerializer.CreateHttpContent(error) }; } public static async Task WriteHttpResponseMessageAsync(HttpResponseMessage httpResponseMessage, HttpResponse contextResponse) diff --git a/src/Facility.AspNetCore/FacilityExceptionHandlerOptions.cs b/src/Facility.AspNetCore/FacilityExceptionHandlerOptions.cs new file mode 100644 index 0000000..4b000bc --- /dev/null +++ b/src/Facility.AspNetCore/FacilityExceptionHandlerOptions.cs @@ -0,0 +1,10 @@ +using Facility.Core.Http; + +namespace Facility.AspNetCore; + +public sealed class FacilityExceptionHandlerOptions +{ + public bool IncludeErrorDetails { get; set; } + + public HttpContentSerializer? ContentSerializer { get; set; } +}