CustomErrorController.java
package edu.ucsb.cs156.frontiers.controllers;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Custom error controller that replaces the default white label error page with a more
* user-friendly error page.
*/
@Controller
@Slf4j
public class CustomErrorController extends BasicErrorController {
public CustomErrorController(ErrorAttributes errorAttributes, ServerProperties properties) {
super(errorAttributes, properties.getError());
}
/**
* Handles error requests and returns a custom error page.
*
* @param request the HTTP request
* @param response the HTTP response
* @return the name of the error view template
*/
@RequestMapping(produces = "text/html")
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
// Get error status
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
int statusCode = 500; // Default to internal server error
if (status != null) {
statusCode = Integer.parseInt(status.toString());
}
// Get error message
String errorMessage = "An unexpected error occurred";
if (statusCode == 404) {
errorMessage =
"The page you are looking for might have been removed or is temporarily unavailable";
} else if (statusCode == 403) {
errorMessage = "You don't have permission to access this resource";
} else if (statusCode == 500) {
errorMessage = "We're sorry, something went wrong on our end";
}
// Get exception details for debugging
Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
String exceptionMessage =
throwable != null ? throwable.getMessage() : "No exception details available";
// Get stack trace
String stackTrace = "";
if (throwable != null) {
for (StackTraceElement element : throwable.getStackTrace()) {
stackTrace += element.toString() + "\n";
}
}
ModelMap model = new ModelMap();
// Add attributes to the model
model.addAttribute("status", statusCode);
model.addAttribute("error", HttpStatus.valueOf(statusCode).getReasonPhrase());
model.addAttribute("message", errorMessage);
model.addAttribute("exceptionMessage", exceptionMessage);
model.addAttribute("stackTrace", stackTrace);
model.addAttribute("timestamp", java.time.LocalDateTime.now());
model.addAttribute("path", request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI));
return new ModelAndView("error", model);
}
}