From 35afb5f73330c3adbf7895437d7b4f07b52ffa25 Mon Sep 17 00:00:00 2001
From: Tucker Siegel <tgsiegel@terpmail.umd.edu>
Date: Sat, 15 Apr 2023 13:57:53 -0400
Subject: [PATCH] expand error logs

---
 .../common/exceptions/BaseExceptions.java     | 12 ++++
 .../exceptions/CustomExceptionHandler.java    | 62 +++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/src/main/java/edu/umd/dawn/common/exceptions/BaseExceptions.java b/src/main/java/edu/umd/dawn/common/exceptions/BaseExceptions.java
index c4f5248..c9b777d 100644
--- a/src/main/java/edu/umd/dawn/common/exceptions/BaseExceptions.java
+++ b/src/main/java/edu/umd/dawn/common/exceptions/BaseExceptions.java
@@ -1,14 +1,26 @@
 package edu.umd.dawn.common.exceptions;
 
 public class BaseExceptions {
+    public static final DawnExceptionParameters METHOD_NOT_ALLOWED =
+            new DawnExceptionParameters(405, "METHOD_NOT_ALLOWED", "method not allowed", "");
+    public static final DawnExceptionParameters NOT_ACCEPTABLE =
+            new DawnExceptionParameters(405, "NOT_ACCEPTABLE", "not acceptable", "");
+    public static final DawnExceptionParameters UNSUPPORTED_MEDIA_TYPE =
+            new DawnExceptionParameters(415, "UNSUPPORTED_MEDIA_TYPE", "unsupported media type", "");
+
     public static final DawnExceptionParameters BAD_REQUEST =
             new DawnExceptionParameters(400, "BAD_REQUEST", "Invalid request submitted", "");
+            
     public static final DawnExceptionParameters INTERNAL_SERVER_ERROR =
             new DawnExceptionParameters(500, "INTERNAL_SERVER_ERROR", "Internal server error", "");
     public static final DawnExceptionParameters OUT_OF_BOUNDS =
             new DawnExceptionParameters(500, "INTERNAL_SERVER_ERROR", "Internal server error", "out of bounds");
     public static final DawnExceptionParameters UNHANDLED_INTERNAL_SERVER_ERROR =
             new DawnExceptionParameters(500, "INTERNAL_SERVER_ERROR", "Internal server error", "unhandled error");
+  
+    public static final DawnExceptionParameters SERVICE_UNAVAILABLE = 
+            new DawnExceptionParameters(503, "SERVICE_UNAVAILABLE", "service unavailable", "");
+
     public static final DawnExceptionParameters FORBIDDEN =
             new DawnExceptionParameters(403, "FORBIDDEN", "user cannot access requested resource", "");
     public static final DawnExceptionParameters INVALID_JWT = new DawnExceptionParameters(
diff --git a/src/main/java/edu/umd/dawn/common/exceptions/CustomExceptionHandler.java b/src/main/java/edu/umd/dawn/common/exceptions/CustomExceptionHandler.java
index 213db06..33e711a 100644
--- a/src/main/java/edu/umd/dawn/common/exceptions/CustomExceptionHandler.java
+++ b/src/main/java/edu/umd/dawn/common/exceptions/CustomExceptionHandler.java
@@ -2,22 +2,56 @@ package edu.umd.dawn.common.exceptions;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.Map;
+import java.util.Set;
+
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
+import org.springframework.beans.ConversionNotSupportedException;
+import org.springframework.beans.TypeMismatchException;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
 import org.springframework.stereotype.Component;
 import org.springframework.validation.BindException;
 import org.springframework.validation.FieldError;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.HttpMediaTypeNotSupportedException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.MissingPathVariableException;
+import org.springframework.web.bind.MissingServletRequestParameterException;
+import org.springframework.web.bind.ServletRequestBindingException;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
+import org.springframework.web.multipart.support.MissingServletRequestPartException;
+import org.springframework.web.servlet.NoHandlerFoundException;
 
 @ControllerAdvice
 @Component
 @Slf4j
 public class CustomExceptionHandler {
 
+    private final Map<Class<?>, DawnExceptionParameters> MVC_EXCEPTION_MAP = Map.ofEntries(
+        Map.entry(HttpRequestMethodNotSupportedException.class, BaseExceptions.METHOD_NOT_ALLOWED),
+        Map.entry(HttpMediaTypeNotSupportedException.class, BaseExceptions.UNSUPPORTED_MEDIA_TYPE),
+        Map.entry(HttpMediaTypeNotAcceptableException.class, BaseExceptions.NOT_ACCEPTABLE),
+        Map.entry(MissingPathVariableException.class, BaseExceptions.INTERNAL_SERVER_ERROR),
+        Map.entry(MissingServletRequestParameterException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(ServletRequestBindingException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(ConversionNotSupportedException.class, BaseExceptions.INTERNAL_SERVER_ERROR),
+        Map.entry(TypeMismatchException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(HttpMessageNotReadableException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(HttpMessageNotWritableException.class, BaseExceptions.INTERNAL_SERVER_ERROR),
+        Map.entry(MethodArgumentNotValidException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(MissingServletRequestPartException.class, BaseExceptions.BAD_REQUEST),
+        Map.entry(NoHandlerFoundException.class, BaseExceptions.NOT_FOUND),
+        Map.entry(AsyncRequestTimeoutException.class, BaseExceptions.SERVICE_UNAVAILABLE)
+    );
+
     @Value("${config.serviceName}")
     private String source;
 
@@ -79,6 +113,34 @@ public class CustomExceptionHandler {
         return returnDawnException(exception);
     }
 
+    // begin common spring mvc exceptions
+    @ExceptionHandler({
+        HttpRequestMethodNotSupportedException.class,
+        HttpMediaTypeNotSupportedException.class,
+        HttpMediaTypeNotAcceptableException.class,
+        MissingPathVariableException.class,
+        MissingServletRequestParameterException.class,
+        ServletRequestBindingException.class,
+        ConversionNotSupportedException.class,
+        TypeMismatchException.class,
+        HttpMessageNotReadableException.class,
+        HttpMessageNotWritableException.class,
+        MethodArgumentNotValidException.class,
+        MissingServletRequestPartException.class,
+        NoHandlerFoundException.class,
+        AsyncRequestTimeoutException.class
+    })
+    public ResponseEntity<Object> handleMvcError(Exception exception, WebRequest webRequest) {
+        Set<Class<?>> classList = MVC_EXCEPTION_MAP.keySet();
+        for (Class<?> clazz : classList) {
+            if (clazz.isInstance(exception)) {
+                return wrapExceptionAs(exception, MVC_EXCEPTION_MAP.get(clazz));
+            }
+        }
+        return wrapExceptionAs(exception, BaseExceptions.UNHANDLED_INTERNAL_SERVER_ERROR);
+    }
+    // end common spring mvc exceptions
+
     @ExceptionHandler(RuntimeException.class)
     public ResponseEntity<Object> handleUnHandledException(RuntimeException exception, WebRequest webRequest) {
         return wrapExceptionAs(exception, BaseExceptions.UNHANDLED_INTERNAL_SERVER_ERROR);
-- 
GitLab