summaryrefslogtreecommitdiff
path: root/Server/ExceptionMiddleware.cs
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2026-05-22 00:52:16 +1000
committerJake Mannens <jake@asger.xyz>2026-05-23 22:22:55 +1000
commit12eaa5814ef20b0910e8d64a753378b6f6797989 (patch)
tree062cf477c29054e0f089cb80f0cd79a9f3b7ccd9 /Server/ExceptionMiddleware.cs
parent6de5d7f5364fe1d54703da6d6b7cb08ea26e939f (diff)
Initial commitwasm-initial
Diffstat (limited to 'Server/ExceptionMiddleware.cs')
-rw-r--r--Server/ExceptionMiddleware.cs64
1 files changed, 64 insertions, 0 deletions
diff --git a/Server/ExceptionMiddleware.cs b/Server/ExceptionMiddleware.cs
new file mode 100644
index 0000000..29d0e10
--- /dev/null
+++ b/Server/ExceptionMiddleware.cs
@@ -0,0 +1,64 @@
+using HyperBooru.ApiModels;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.Json.Serialization.Metadata;
+
+namespace HyperBooru;
+
+// Middleware class to intercept API controller exceptions and
+// return said exceptions to API clients as serialized JSON objects
+public sealed class ExceptionMiddleware {
+ private RequestDelegate next;
+
+ public ExceptionMiddleware(RequestDelegate next) =>
+ this.next = next;
+
+ public async Task Invoke(HttpContext context) {
+ try {
+ await next(context);
+ } catch(HBException e) {
+ context.Response.ContentType = "application/json";
+ context.Response.StatusCode =
+ e.GetType().GetCustomAttribute<ExceptionStatusCodeAttribute>()?.StatusCode ??
+ StatusCodes.Status500InternalServerError;
+
+ await context.Response.WriteAsJsonAsync(e);
+
+ var x = 1;
+ } catch(Exception) {
+ context.Response.StatusCode = StatusCodes.Status500InternalServerError;
+ context.Response.ContentType = "application/json";
+
+ context.Response.Clear();
+
+ await context.Response.WriteAsync(string.Empty);
+ }
+ }
+}
+
+// This class is needed as the JSON serializer often fails to serialize
+// members of the native 'Exception' class
+public sealed class ExceptionJsonResolver : DefaultJsonTypeInfoResolver {
+ public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) {
+ var info = base.GetTypeInfo(type, options);
+
+ if(!typeof(Exception).IsAssignableFrom(type))
+ return info;
+
+ string[] excludedProps = [
+ "data",
+ "hResult",
+ "helpLink",
+ "innerException",
+ "source",
+ "stackTrace",
+ "targetSite"
+ ];
+
+ foreach(var p in info.Properties.Where(p => excludedProps.Contains(p.Name)))
+ p.ShouldSerialize = (_, _) => false;
+
+ return info;
+ }
+}