|
| 1 | +package org.genspectrum.lapis.controller |
| 2 | + |
| 3 | +import jakarta.servlet.http.HttpServletRequest |
| 4 | +import jakarta.servlet.http.HttpServletResponse |
| 5 | +import mu.KotlinLogging |
| 6 | +import org.springframework.boot.autoconfigure.web.ErrorProperties |
| 7 | +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController |
| 8 | +import org.springframework.boot.web.servlet.error.ErrorAttributes |
| 9 | +import org.springframework.http.MediaType |
| 10 | +import org.springframework.stereotype.Component |
| 11 | +import org.springframework.web.bind.annotation.RequestMapping |
| 12 | +import org.springframework.web.servlet.ModelAndView |
| 13 | +import org.springframework.web.servlet.View |
| 14 | +import org.springframework.web.servlet.support.ServletUriComponentsBuilder |
| 15 | + |
| 16 | +private val log = KotlinLogging.logger { } |
| 17 | + |
| 18 | +@Component |
| 19 | +class ErrorController(errorAttributes: ErrorAttributes) : |
| 20 | + BasicErrorController(errorAttributes, ErrorProperties()) { |
| 21 | + |
| 22 | + @RequestMapping(produces = [MediaType.TEXT_HTML_VALUE]) |
| 23 | + override fun errorHtml(request: HttpServletRequest, response: HttpServletResponse): ModelAndView { |
| 24 | + val modelAndView = super.errorHtml(request, response) |
| 25 | + |
| 26 | + response.addHeader("Content-Type", MediaType.TEXT_HTML_VALUE) |
| 27 | + |
| 28 | + val urlPrefix = removeErrorSegmentFromUrl(ServletUriComponentsBuilder.fromCurrentRequest().toUriString()) |
| 29 | + val url = "$urlPrefix/swagger-ui/index.html" |
| 30 | + |
| 31 | + log.debug { "Generated url $url to Swagger UI in 'not found page'" } |
| 32 | + |
| 33 | + modelAndView.view = NotFoundView(url) |
| 34 | + return modelAndView |
| 35 | + } |
| 36 | + |
| 37 | + fun removeErrorSegmentFromUrl(url: String): String { |
| 38 | + val lastSlashIndex = url.trimEnd('/').lastIndexOf("error") |
| 39 | + return url.substring(0, lastSlashIndex).trim('/') |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +data class NotFoundView(private val url: String?) : View { |
| 44 | + |
| 45 | + override fun render(model: MutableMap<String, *>?, request: HttpServletRequest, response: HttpServletResponse) { |
| 46 | + val html: String = """ |
| 47 | + <!DOCTYPE html> |
| 48 | + <html lang="en"> |
| 49 | + <head> |
| 50 | + <meta charset="UTF-8"> |
| 51 | + <title>Error 404</title> |
| 52 | + </head> |
| 53 | + <body> |
| 54 | + <h1>LAPIS</h1> |
| 55 | + <h3>Page not found!</h3> |
| 56 | + <a href="$url">Visit our swagger-ui</a> |
| 57 | + </body> |
| 58 | + </html> |
| 59 | + """.trimIndent() |
| 60 | + |
| 61 | + response.outputStream.write(html.toByteArray()) |
| 62 | + } |
| 63 | +} |
0 commit comments