All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.infobip.kafkistry.webapp.controller.BaseController.kt Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
package com.infobip.kafkistry.webapp.controller

import com.infobip.kafkistry.utils.deepToString
import com.infobip.kafkistry.webapp.CompositeRequestInterceptor
import com.infobip.kafkistry.webapp.WebHttpProperties
import com.infobip.kafkistry.webapp.menu.MenuItemsInjector
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.servlet.ModelAndView
import jakarta.servlet.RequestDispatcher
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse

@Controller
abstract class BaseController {

    private val log = LoggerFactory.getLogger(BaseController::class.java)

    @Autowired
    private lateinit var compositeInterceptor: CompositeRequestInterceptor

    @Autowired
    private lateinit var menuItemsInjector: MenuItemsInjector

    @Autowired
    private lateinit var webHttpProperties: WebHttpProperties

    @ExceptionHandler(Exception::class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    fun handleKafkistryException(
        request: HttpServletRequest, response: HttpServletResponse, exception: Exception
    ): ModelAndView {
        response.setHeader("exception-html", "true")
        val ajaxRequest = request.getHeader("ajax")?.let { it == "true" } ?: false
        val httpStatus = HttpStatus.resolve(response.status)
            .takeIf { it != HttpStatus.OK }
            ?: HttpStatus.INTERNAL_SERVER_ERROR
        val servletException = request.getAttribute("jakarta.servlet.error.exception") as? Exception
        val error = exception.takeUnless {
            it.javaClass == java.lang.Exception::class.java && it.cause == null && it.message == null
        } ?: servletException ?: exception
        val exceptionMessage = when (httpStatus) {
            HttpStatus.NOT_FOUND -> "Invalid url path: '" + request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) + "'"
            HttpStatus.FORBIDDEN -> "Access denied for '" + request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) + "'"
            else -> error.deepToString()
        }
        val attrsDump = if (webHttpProperties.dumpRequestAttributes) {
            request.attributeNames.toList().associateWith {
                when (val attr = request.getAttribute(it) ?: null) {
                    is Throwable -> attr.deepToString()
                    else -> attr.toString()
                }
            }
        } else {
            emptyMap()
        }
        return ModelAndView(
            if (ajaxRequest) "registryExceptionAlert" else "registryException",
            mutableMapOf(
                "httpStatus" to httpStatus,
                "exceptionMessage" to exceptionMessage,
                "attrsDump" to attrsDump,
            )
        ).also {
            log.error("Exception occurred on {} '{}'\nattrsDump={}", request.method, request.requestURI, attrsDump, exception)
            //injecting model to view because injecting interceptor is not invoked on error handling
            compositeInterceptor.injectModel(it, request)
            menuItemsInjector.injectMenuItems(it)
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy