【Spring Boot】例外とレスポンスを紐づけてエラー処理を簡単にやる


環境

Spring Boot 2.2.4.RELEASE
Kotlin 1.3.61
axios 0.19.2
vue 2.6.11

環境は以下の記事のまんま

作り方

単純に例外レスポンス200以外っていう仕組みを作る
例えばログイン処理の中で、パスワードが間違ってた時にInCorrectPasswordExceptionが発生するものとして作る

まずは、どういうときに起きる例外かっていうのを作っておく

InCorrectPasswordException.kt
class InCorrectPasswordException : RuntimeException()

それ用のExceptionを作っておいて

ExceptionHandler.kt
@ControllerAdvice
class ExceptionHandler {

    private final val descriptionKey = "Description"

    @ExceptionHandler(InCorrectPasswordException::class)
    @ResponseStatus( HttpStatus.BAD_REQUEST )
    fun handleInCorrectPasswordException(
            response: HttpServletResponse
    ){
        response.setHeader( descriptionKey , "InCorrectPassword" )
    }

}

適当な場所にクラスを作って@ControllerAdviceを付ける
今回はヘッダに詳細を追加してそこにどういうエラーかを書いておく

@ExceptionHandlerは何の例外が出たらこのメソッドが呼ばれるかっていう印
@ResponseStatusは返るレスポンスのステータスを指定
普通のControllerと同じように引数にHttpServletResponseとかHttpServletRequestも受け取れるし、他にもThrowableとかも受け取れるからメソッドの中で加工してもOK

僕なりの非推奨

ちゃんと自前のExceptionを作ること

例えば@ExceptionHandler(Exception::class)とかやってすべてのExceptionを受け取るようにしてしまうと、
ほんとに何かバックエンド側で問題があった場合にエラーの内容を書き換えてしまうことになるから注意
(そういうことはないorそれでもクライアントにエラーの中身を見られたくないって場合なら別だけど・・・)

後、僕はいつも@ControllerAdviceを使うときはBodyじゃなくHeaderに追加
変更じゃなくて追加
エラーの詳細が書いてあるBodyを上書きしてしまうと何があったか追跡するのが大変になると思う
エラーの詳細って一番上の一文ググるだけで回答出てきたりするじゃん?
だから元の情報は残したまま、独自の情報を載せるようなやり方がいいと思う

開発環境だけ適用されるみたいなことができると強いかもね