|
| 1 | +package com.openbankproject.hydra.auth.controller; |
| 2 | + |
| 3 | +import org.slf4j.Logger; |
| 4 | +import org.slf4j.LoggerFactory; |
| 5 | +import org.springframework.beans.factory.annotation.Value; |
| 6 | +import org.springframework.ui.Model; |
| 7 | +import org.springframework.web.bind.MissingServletRequestParameterException; |
| 8 | +import org.springframework.web.bind.UnsatisfiedServletRequestParameterException; |
| 9 | +import org.springframework.web.bind.annotation.ControllerAdvice; |
| 10 | +import org.springframework.web.bind.annotation.ExceptionHandler; |
| 11 | + |
| 12 | +/** |
| 13 | + * Without this, a request that fails Spring's @PostMapping(params=...) matching |
| 14 | + * (e.g. a consent form submitted with no permission checkbox selected) never reaches |
| 15 | + * a controller method, so none of the per-endpoint try/catch blocks in IndexController |
| 16 | + * run. It falls through to the default error view with a blank message instead. |
| 17 | + */ |
| 18 | +@ControllerAdvice |
| 19 | +public class GlobalExceptionHandler { |
| 20 | + private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); |
| 21 | + |
| 22 | + @Value("${obp.base_url:#}") |
| 23 | + private String obpBaseUrl; |
| 24 | + @Value("${logo.bank.enabled:false}") |
| 25 | + private String showBankLogo; |
| 26 | + @Value("${logo.bank.url:#}") |
| 27 | + private String bankLogoUrl; |
| 28 | + @Value("${show_unhandled_errors:false}") |
| 29 | + private boolean showUnhandledErrors; |
| 30 | + |
| 31 | + @ExceptionHandler(UnsatisfiedServletRequestParameterException.class) |
| 32 | + public String handleUnsatisfiedServletRequestParameter(UnsatisfiedServletRequestParameterException e, Model model) { |
| 33 | + logger.warn("Form submission rejected: {}", e.getMessage()); |
| 34 | + addCommonAttributes(model); |
| 35 | + model.addAttribute("errorMsg", "The form is missing one or more required fields (" + e.getMessage() |
| 36 | + + "). If this form has permission checkboxes, make sure at least one is selected before submitting."); |
| 37 | + return "error"; |
| 38 | + } |
| 39 | + |
| 40 | + @ExceptionHandler(MissingServletRequestParameterException.class) |
| 41 | + public String handleMissingServletRequestParameter(MissingServletRequestParameterException e, Model model) { |
| 42 | + logger.warn("Form submission rejected: {}", e.getMessage()); |
| 43 | + addCommonAttributes(model); |
| 44 | + model.addAttribute("errorMsg", "The form is missing a required field: " + e.getParameterName() + "."); |
| 45 | + return "error"; |
| 46 | + } |
| 47 | + |
| 48 | + // Catches anything a controller method itself doesn't try/catch (this class's other handlers |
| 49 | + // above take precedence for their specific exception types). Same showUnhandledErrors |
| 50 | + // convention IndexController's own per-endpoint catch-all blocks use. |
| 51 | + @ExceptionHandler(Exception.class) |
| 52 | + public String handleUnhandled(Exception e, Model model) { |
| 53 | + logger.error("Unhandled exception reached GlobalExceptionHandler", e); |
| 54 | + addCommonAttributes(model); |
| 55 | + model.addAttribute("errorMsg", showUnhandledErrors ? e.toString() : "Internal Server Error"); |
| 56 | + return "error"; |
| 57 | + } |
| 58 | + |
| 59 | + private void addCommonAttributes(Model model) { |
| 60 | + model.addAttribute("obpBaseUrl", obpBaseUrl); |
| 61 | + model.addAttribute("showBankLogo", showBankLogo); |
| 62 | + model.addAttribute("bankLogoUrl", bankLogoUrl); |
| 63 | + } |
| 64 | +} |
0 commit comments