From 5e5011e98dd7e2f18d4d799be5b7a8adfbdccd02 Mon Sep 17 00:00:00 2001 From: Mark Junker Date: Mon, 22 Nov 2021 09:42:11 +0100 Subject: [PATCH] New attribute WebDavAnyExceptionFilterAttribute Ensures that - in the sample server - all exceptions are returned as multi-status responses. Incorporates the changes from #38. Maybe we need to return the error element too? --- .../Controllers/WebDavController.cs | 2 ++ .../WebDavAnyExceptionFilterAttribute.cs | 35 +++++++++++++++++++ .../Filters/WebDavExceptionFilterAttribute.cs | 18 ++++++---- .../Model/WebDavStatusCode.cs | 5 +++ 4 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavAnyExceptionFilterAttribute.cs diff --git a/sample/FubarDev.WebDavServer.Sample.AspNetCore/Controllers/WebDavController.cs b/sample/FubarDev.WebDavServer.Sample.AspNetCore/Controllers/WebDavController.cs index 7882caba..bc11ae3a 100644 --- a/sample/FubarDev.WebDavServer.Sample.AspNetCore/Controllers/WebDavController.cs +++ b/sample/FubarDev.WebDavServer.Sample.AspNetCore/Controllers/WebDavController.cs @@ -1,4 +1,5 @@ using FubarDev.WebDavServer.AspNetCore; +using FubarDev.WebDavServer.AspNetCore.Filters; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -8,6 +9,7 @@ namespace FubarDev.WebDavServer.Sample.AspNetCore.Controllers { [Route("_dav/{*path}")] [Authorize] + [WebDavAnyExceptionFilter] public class WebDavController : WebDavControllerBase { public WebDavController( diff --git a/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavAnyExceptionFilterAttribute.cs b/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavAnyExceptionFilterAttribute.cs new file mode 100644 index 00000000..c087cc5c --- /dev/null +++ b/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavAnyExceptionFilterAttribute.cs @@ -0,0 +1,35 @@ +// +// Copyright (c) Fubar Development Junker. All rights reserved. +// + +using System.Threading.Tasks; + +using FubarDev.WebDavServer.Model; + +using Microsoft.AspNetCore.Mvc.Filters; + +namespace FubarDev.WebDavServer.AspNetCore.Filters +{ + /// + /// Attribute to handle exception filtering for WebDAV requests. + /// + public class WebDavAnyExceptionFilterAttribute : WebDavExceptionFilterAttribute + { + /// + public override async Task OnExceptionAsync(ExceptionContext context) + { + await base.OnExceptionAsync(context); + + if (context.ExceptionHandled) + { + return; + } + + // Return an internal server error status for all other exceptions + context.Result = BuildResultForStatusCode( + context, + WebDavStatusCode.InternalServerError); + context.ExceptionHandled = true; + } + } +} diff --git a/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavExceptionFilterAttribute.cs b/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavExceptionFilterAttribute.cs index 0decf517..a83df403 100644 --- a/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavExceptionFilterAttribute.cs +++ b/src/FubarDev.WebDavServer.AspNetCore/Filters/WebDavExceptionFilterAttribute.cs @@ -15,6 +15,9 @@ namespace FubarDev.WebDavServer.AspNetCore.Filters { + /// + /// Attribute to handle exception filtering for WebDAV requests. + /// public class WebDavExceptionFilterAttribute : ExceptionFilterAttribute { /// @@ -33,11 +36,11 @@ public override void OnException(ExceptionContext context) context.ExceptionHandled = true; return; case WebDavException webDavException: - context.Result = BuildResultForStatusCode(context, webDavException.StatusCode, webDavException.Message); + context.Result = BuildResultForStatusCode(context, webDavException.StatusCode); context.ExceptionHandled = true; return; - case UnauthorizedAccessException unauthorizedAccessException: - context.Result = BuildResultForStatusCode(context, WebDavStatusCode.Forbidden, unauthorizedAccessException.Message); + case UnauthorizedAccessException: + context.Result = BuildResultForStatusCode(context, WebDavStatusCode.Forbidden); context.ExceptionHandled = true; return; } @@ -50,10 +53,10 @@ public override void OnException(ExceptionContext context) context.Exception.Message); } - private IActionResult BuildResultForStatusCode( + protected static IActionResult BuildResultForStatusCode( ExceptionContext context, WebDavStatusCode statusCode, - string optionalMessage) + string? optionalMessage = null) { switch (statusCode) { @@ -74,7 +77,10 @@ private IActionResult BuildResultForStatusCode( ItemsElementName = new[] { ItemsChoiceType2.status, }, Items = new object[] { - new Status(context.HttpContext.Request.Protocol, statusCode, optionalMessage).ToString(), + new Status( + context.HttpContext.Request.Protocol, + statusCode, + optionalMessage ?? context.Exception.Message).ToString(), }, }, }, diff --git a/src/FubarDev.WebDavServer/Model/WebDavStatusCode.cs b/src/FubarDev.WebDavServer/Model/WebDavStatusCode.cs index e254f03d..ebbae099 100644 --- a/src/FubarDev.WebDavServer/Model/WebDavStatusCode.cs +++ b/src/FubarDev.WebDavServer/Model/WebDavStatusCode.cs @@ -101,6 +101,11 @@ public enum WebDavStatusCode /// FailedDependency = 424, + /// + /// The Internal Server Error (500) status code + /// + InternalServerError = HttpStatusCode.InternalServerError, + /// /// The Not Implemented (501) status code ///