LoginSignup
2
6

More than 5 years have passed since last update.

SpringBootでエラーハンドリング

Posted at

内容

前回の、INSERT用Serviceクラスでは同じIDでリクエストを行うと、そのIDのUPDATE処理となってしまうため、既に存在するIDでリクエストがきた場合はエラーを返すように修正

Exceptionクラス

RuntimeException を継承して、独自Exceptionクラスを生成

public class DuplicateException extends RuntimeException {

    private String type;
    private Long id; 

}

Repositoryクラス

論理削除(delete_flag=1)のレコードはSELECT時の対象外としているため、論理削除されたレコードも抽出できるようにクエリを追加

    @Query(value="SELECT * FROM hotel WHERE id = :id ", nativeQuery=true)
    Hotel findHotelById(@Param("id") Long id);

Serviceクラス

既にホテルIDが存在した場合は、先ほど作成したExceptionを投げるように修正

    public HotelInsertResponseBody insertHotels(Hotel hotel) {
        // transform entity information as response as need
        Hotel check = hotelRepository.findHotelById(hotel.getId());
        if(check != null){
            throw new DuplicateException("hotel" ,hotel.getId());
        }
        hotel.setRegisterDatetime(new Timestamp(System.currentTimeMillis()));
        hotel.setRegisterPerson(Utils.API_NAME);
        Hotel res = hotelRepository.save(hotel);
        HotelInfo hotelInfo = new HotelInfo(res.getId(), res.getName(), res.getLatitude(), res.getLongitude());
        return new HotelInsertResponseBody(hotelInfo);
    }

Exception Handlerクラス

@ExceptionHandlerで、ハンドリングしたいクラスを指定します。
さらにハンドリングした際にエラーの詳細情報を作成し、エラーレスポンスとして返すようにします。

    @ExceptionHandler(DuplicateException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleException(DuplicateException e) {
        log.error("Request parameter validation failed", e);

        String type = e.getType();
        Long id = e.getId();
        HotelError error = HotelError.DUPLICATE_ID_ERROR;
        String detailMessage = type + " id=" + id + " is already exist.";
        return createErrorResponse(
                HttpStatus.BAD_REQUEST, 
                error, detailMessage,
                ErrorInfo.Type.VALIDATION );      
    }

確認

既存レコード (id = 105)

*************************** 1. row ***************************
               id: 105
             name: HIJ Hotel
         latitude: NULL
        longitude: NULL
          address: NULL
     country_code: NULL
        city_code: NULL
            grade: NULL
         facility: NULL
       image_path: NULL
register_datetime: 2016-09-12 16:21:23
  register_person: test
  update_datetime: NULL
    update_person: NULL
      delete_flag: 1
  delete_datetime: 2016-09-12 17:15:20
    delete_person: test

リクエスト

既存レコード (id = 105)のINSERTリクエストを投げます。

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
  "header": {
    "countryCode": "US",
    "currencyCode": "USD",
    "languageCode": "en",
    "uid": "string",
    "userAgent": "string",
    "userIp": "string"
  },
  "body": {
    "id": 105,
    "name": "HIJ HOTEL"
  }
}' 'http://localhost:8080/hotel/insert'

レスポンス

設定したエラーレスポンスが返ってくることが確認できました。

{
  "status": 400,
  "error": {
    "code": "HTLERR100",
    "message": "Duplicate id error",
    "type": "VALIDATION",
    "detailMessage": "hotel id=105 is already exist.",
    "invalidParameters": null
  }
}
2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6