Skip to content

Commit c118daa

Browse files
committed
Refactored exception filter to increase readability
1 parent 3836527 commit c118daa

File tree

2 files changed

+50
-35
lines changed

2 files changed

+50
-35
lines changed
Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,72 @@
11
using System;
22
using CoffeeCard.Common.Errors;
3+
using Microsoft.AspNetCore.Hosting;
34
using Microsoft.AspNetCore.Http;
45
using Microsoft.AspNetCore.Mvc;
56
using Microsoft.AspNetCore.Mvc.Filters;
6-
using Serilog;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.Extensions.Logging;
79

810
namespace CoffeeCard.WebApi.Helpers
911
{
1012
/// <summary>
1113
/// Exception filter for handling API exceptions and returning appropriate HTTP status codes and error messages.
1214
/// </summary>
13-
public class ApiExceptionFilter : ExceptionFilterAttribute
15+
public class ApiExceptionFilter(IWebHostEnvironment environment, ILogger<ApiExceptionFilter> logger)
16+
: ExceptionFilterAttribute
1417
{
18+
private readonly ILogger<ApiExceptionFilter> _logger = logger;
19+
private readonly IWebHostEnvironment _environment = environment;
20+
1521
/// <inheritdoc/>
1622
public override void OnException(ExceptionContext context)
1723
{
18-
ApiError apiError;
19-
switch (context.Exception)
20-
{
21-
case ConflictException exception:
22-
apiError = new ApiError(exception.Message);
23-
context.HttpContext.Response.StatusCode = StatusCodes.Status409Conflict;
24-
break;
25-
case ApiException exception:
26-
{
27-
apiError = new ApiError(exception.Message);
28-
context.HttpContext.Response.StatusCode = exception.StatusCode;
29-
break;
30-
}
31-
case UnauthorizedAccessException _:
32-
apiError = new ApiError("Unauthorized Access");
33-
context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
34-
break;
35-
default:
36-
{
37-
Log.Error(context.Exception, "Unhandled exception caught");
38-
39-
#if !DEBUG
40-
var msg = "An unhandled error occurred.";
41-
#else
42-
var msg = context.Exception.GetBaseException().Message;
43-
#endif
44-
45-
apiError = new ApiError(msg);
46-
context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
47-
break;
48-
}
49-
}
24+
var exception = context.Exception;
25+
26+
var responseMessage = GetResponseMessage(exception);
27+
var apiError = new ApiError(responseMessage);
28+
context.HttpContext.Response.StatusCode = GetStatusCode(exception);
29+
LogException(exception);
5030

5131
// always return a JSON result
5232
context.Result = new JsonResult(apiError);
33+
context.ExceptionHandled = true;
5334

5435
base.OnException(context);
5536
}
37+
38+
private string GetResponseMessage(Exception exception)
39+
{
40+
return exception switch
41+
{
42+
// We consider our own exceptions fine for sending to users
43+
ApiException apiException => apiException.Message,
44+
// To avoid leaking internal errors, we only show the exception message in dev
45+
_ => _environment.IsDevelopment()
46+
? exception.GetBaseException().Message
47+
: "Unhandled exception caught"
48+
};
49+
}
50+
51+
private int GetStatusCode(Exception exception)
52+
{
53+
return exception switch
54+
{
55+
ApiException apiException => apiException.StatusCode,
56+
_ => StatusCodes.Status500InternalServerError
57+
};
58+
}
59+
60+
private void LogException(Exception exception)
61+
{
62+
if (exception is ApiException apiException)
63+
{
64+
_logger.LogWarning(apiException, "Unintended user flow occured");
65+
}
66+
else
67+
{
68+
_logger.LogError(exception, "Unhandled exception caught");
69+
}
70+
}
5671
}
5772
}

coffeecard/CoffeeCard.WebApi/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public void ConfigureServices(IServiceCollection services)
184184
// Setup filter to catch outgoing exceptions
185185
services.AddControllers(options =>
186186
{
187-
options.Filters.Add(new ApiExceptionFilter());
187+
options.Filters.Add<ApiExceptionFilter>();
188188
options.Filters.Add(new ReadableBodyFilter());
189189
})
190190
.AddJsonOptions(options =>

0 commit comments

Comments
 (0)