Fix production DB driver issue and root path 500 error
- Removed hardcoded `driver-class-name` from `application.yaml` to enable Spring Boot's driver auto-detection, fixing the startup failure in production where H2 driver was being used with a PostgreSQL URL. - Updated `ApiExceptionHandler` to handle `NoResourceFoundException`, ensuring that unmapped paths (like `/`) return a 404 Not Found response instead of a 500 Internal Server Error. - Added `NotFoundControllerTest` to verify the fix. Co-authored-by: devitq <118541411+devitq@users.noreply.github.com>
This commit is contained in:
co-authored by
devitq
parent
b4d3ee6b48
commit
cc02ccac01
@@ -11,20 +11,21 @@ import org.springframework.web.bind.MethodArgumentNotValidException
|
|||||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus
|
import org.springframework.web.bind.annotation.ResponseStatus
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice
|
import org.springframework.web.bind.annotation.RestControllerAdvice
|
||||||
|
import org.springframework.web.servlet.resource.NoResourceFoundException
|
||||||
import org.springframework.web.server.ResponseStatusException
|
import org.springframework.web.server.ResponseStatusException
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
class ApiExceptionHandler {
|
class ApiExceptionHandler {
|
||||||
private val log = LoggerFactory.getLogger(javaClass)
|
private val log = LoggerFactory.getLogger(javaClass)
|
||||||
|
|
||||||
@ExceptionHandler(EntityNotFoundException::class)
|
@ExceptionHandler(EntityNotFoundException::class, NoResourceFoundException::class)
|
||||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
fun handleNotFound(exception: EntityNotFoundException): ErrorResponse {
|
fun handleNotFound(exception: Exception): ErrorResponse {
|
||||||
val traceId = currentTraceId()
|
val traceId = currentTraceId()
|
||||||
log.warn("Entity not found: traceId='{}', message='{}'", traceId, exception.message)
|
log.warn("Resource not found: traceId='{}', message='{}'", traceId, exception.message)
|
||||||
|
|
||||||
return ErrorResponse(
|
return ErrorResponse(
|
||||||
message = exception.message ?: "Entity not found",
|
message = exception.message ?: "Resource not found",
|
||||||
traceId = traceId,
|
traceId = traceId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ spring:
|
|||||||
url: ${SPRING_DATASOURCE_URL:jdbc:h2:mem:movienight;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE}
|
url: ${SPRING_DATASOURCE_URL:jdbc:h2:mem:movienight;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE}
|
||||||
username: ${SPRING_DATASOURCE_USERNAME:sa}
|
username: ${SPRING_DATASOURCE_USERNAME:sa}
|
||||||
password: ${SPRING_DATASOURCE_PASSWORD:}
|
password: ${SPRING_DATASOURCE_PASSWORD:}
|
||||||
driver-class-name: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME:org.h2.Driver}
|
|
||||||
hikari:
|
hikari:
|
||||||
maximum-pool-size: ${SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE:20}
|
maximum-pool-size: ${SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE:20}
|
||||||
minimum-idle: ${SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE:5}
|
minimum-idle: ${SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE:5}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.project.movienight.controllers
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureMockMvc(addFilters = false)
|
||||||
|
class NotFoundControllerTest {
|
||||||
|
@Autowired
|
||||||
|
private lateinit var mockMvc: MockMvc
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `requesting non-existent path should return 404 JSON response`() {
|
||||||
|
mockMvc
|
||||||
|
.perform(get("/non-existent-path"))
|
||||||
|
.andExpect(status().isNotFound)
|
||||||
|
.andExpect(jsonPath("$.message").exists())
|
||||||
|
.andExpect(jsonPath("$.traceId").exists())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `requesting root path should return 404 JSON response`() {
|
||||||
|
mockMvc
|
||||||
|
.perform(get("/"))
|
||||||
|
.andExpect(status().isNotFound)
|
||||||
|
.andExpect(jsonPath("$.message").exists())
|
||||||
|
.andExpect(jsonPath("$.traceId").exists())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user