アプリ全体の共通エラーハンドリングを実装する。
存在しないURLへのリクエスト:NotFound(HttpStatus=404)を返す
ハンドリングしていないエラー(Bug):InternalServerError(HttpStatus-500)を返す
デフォルトではSpringBootが、JSONでエラーレスポンスを返すかブラウザでアクセスした場合はWhitelabel Error Pageが表示される。セキュリティの観点からもエラーハンドリング をカスタマイズするのがベター。
エラー発生時のレスポンスモデルを用意する
data class ApplicationError(
val detailCode: String,
val message: String
)
次にSpring公式ページを参考にErrorControllerクラスを実装する。サンプルコードが無いのでErrorControllerのクラスを確認し実装が必要なメソッドを確認して実装。
詳細コード、メッセージは別途体系化するとして、ここではひとまずの値を設定。
@RestController
@RequestMapping("/error")
class CustomErrorController : ErrorController {
private val log = LogFactory.getLog(CustomErrorController::class.java)
@Value("\${server.error.path:\${error.path:/error}}")
private val errorPath: String = ""
override fun getErrorPath(): String {
return errorPath
}
@RequestMapping
fun handleError(request: HttpServletRequest): ResponseEntity<ApplicationError> {
val statusCode = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)
if (statusCode == HttpStatus.NOT_FOUND.value()) {
val error = ApplicationError("E1002", "Request url is incorrect.")
return ResponseEntity<ApplicationError>(error, HttpStatus.NOT_FOUND)
}
log.error(request.getAttribute(RequestDispatcher.ERROR_EXCEPTION))
val error = ApplicationError("E1003", "Unknown error was happened.")
return ResponseEntity<ApplicationError>(error, HttpStatus.INTERNAL_SERVER_ERROR)
}
}
結果を確認
NotFound
マッピングしていないURLにリクエストを実行して、HttpStatusが404になっている事、レスポンスモデルが意図通りのモデルであることを確認。
http://localhost:8080/tasks/12345/incorrect
InternalServerError
コードに一時的にバグを埋め込んでアクセス、HttpStatusが500になっている事、レスポンスモデルが意図通りのモデルであることを確認。
@GetMapping("/{taskId}")
@ResponseBody
@ResponseStatus(HttpStatus.OK)
fun getTask(@PathVariable("taskId") taskId: Int): Task {
log.info("getTask is called with taskId($taskId).")
// bug
val a = 1 / 0
return taskService.getTask(taskId)
}
http://localhost:8080/tasks/12345
ログも意図通りに出力されている事を確認。
2021-02-11 15:26:19.347 ERROR 10065 --- [nio-8080-exec-4] c.e.b.controller.CustomErrorController : org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ArithmeticException: / by zero
コメントを残す