이번에는 에러, 형식에 맞지않는 요청이 들어왔을때 그대로 실행하지 않고 오류에 대응하는 것을 만든다.
예외 처리(Exception Handling) 혹은 오류 처리(Trouble Shooting)란 실행 흐름상 오류가 발생했을 때 오류를 그대로 실행시키지 않고 오류에 대응하는 방법을 제시하는 개념이나 하드웨어 구조
기존에 study 프로젝트 안에 blog라는 폴더를 만들고 그 blog 페키지 안에 코드를 작성해서 API,DB를 다루는 작업을 했었다면,

handler는 study 와 같은 위치에 있는 core라는 이름의 package를 만든다.

파일들을 보면 core안에 exception과 response라는 package를 만들었고, exception안에 파일들은 예외처리에 대한 내용들이 담겨있고, response안에 있는 errorresponse는 어떻게 처리한것에 대한 것을 실행할 코드가 담겨있다.
이제 예외처리하는 방식을 알았으니, 이 코드를 실행시키기 위해 데이터를 처리하는 부분인 blog의 BlogService의 searchKaKao 을 실행하기 전에 검증하는 코드를 작성해줘야한다.
추가 검증한다는 코드의 내용은 아래와 같다.

코드 아래에 enum class로 예외 메시지를 선언한 코드를 작성하고 아래에서 가져오는 방식으로 진행했다.

//blogDto로 들어온 값에 문제가있는지 확인하는 부분. Exception 전처리
val msgList = mutableListOf<ExceptionMsg>()
if (blogDto.query.trim().isEmpty()) {
msgList.add(ExceptionMsg.EMPTY_QUERY) //EMPTY_QUERY("query parameter required")
}
if (blogDto.sort.trim() !in arrayOf("accuracy", "recency")) {
msgList.add(ExceptionMsg.NOT_IN_SORT) //NOT_IN_SORT("sort parameter one of accuracy and recency")
}
when {
blogDto.page < 1 -> msgList.add(ExceptionMsg.LESS_THAN_MIN) // 1보다 작다면,LESS_THAN_MIN("page is less than min")
blogDto.page > 50 -> msgList.add(ExceptionMsg.MORE_THAN_MAX) // 50보다 크다면, MORE_THAN_MAX("page is more than max")
}
// 위에서 문제가 있어서 msgList에 하나라도 데이터가 있다면, 오류 발생이므로 Exception이 동작해야함
// msgList가 비어있지 않다면, 존재한다면
if (msgList.isNotEmpty()){
val message = msgList.joinToString { it.msg } //담긴 내용을 message에 담아서
throw InvalidInputException(message) // InvalidInputException에 msgList 내용을 던진다.
}
코드를 보면
1. query가 비어있는지 확인
2. Sort가 있는지 확인
3. 크기가 1보다 작거나 50보다 큰지 확인
세가지 항목을 확인해서 각각 msgList에 에러 메시지를 담고
밑에 msgList가 비어있지 않다면 msgList에 추가된 내용을 message에 담고 담은 내용을 InvalidInputException에 담아서 던져준다.
Main
ㄴ Kotlin
ㄴ study
ㄴ blog
ㄴ controller
ㄴ dto
ㄴ entity
ㄴ response
ㄴ service //수정됨, 예외처리
ㄴ StudyApplication.kt
//추가된 내용
ㄴ core
ㄴ exception
ㄴ CustomExceptionHandler
ㄴ InvalidInputException
ㄴ response
ㄴ ErrorResponse
어플리케이션을 실행한다(build study).
"C:\Program Files\Java\jdk-20\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2023.3.5\lib\idea_rt.jar=51989:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2023.3.5\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\Users\SmileB\Desktop\kakaopay\SpringKotlinAPI\study\build\classes\kotlin\main;C:\Users\SmileB\Desktop\kakaopay\SpringKotlinAPI\study\build\resources\main;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-web\3.2.4\a74df12b71060da7c8e87f9a8c2ef4ea43fc8017\spring-boot-starter-web-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.module\jackson-module-kotlin\2.15.4\8801daa3840336ff3de969ce4cb8a3b1a9be0412\jackson-module-kotlin-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-reflect\1.9.23\ab01e1cc8428c2140891318838ad7039f6fa389a\kotlin-reflect-1.9.23.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.9.23\dbaadea1f5e68f790d242a91a38355a83ec38747\kotlin-stdlib-1.9.23.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-data-jpa\3.2.4\d8c5f393d9b18d96021b3e02d80e4356c5cbe0f7\spring-boot-starter-data-jpa-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webflux\6.1.5\f4868f747fc029e350cfdf0727f67cac359ee1af\spring-webflux-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-json\3.2.4\ef3f72369ce7f6f7a7b02c0b23e60ef5bdf581b1\spring-boot-starter-json-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter\3.2.4\842cf7f0ed2ecfef3011f3191fc53c59ceed752\spring-boot-starter-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-tomcat\3.2.4\ffa632eeaaf1a4e807ec4bbcc1938f7d43096472\spring-boot-starter-tomcat-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webmvc\6.1.5\92809fce136e0b662dc9325529443386ba5ec2c6\spring-webmvc-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-web\6.1.5\4f4e92cc52ee33260f1ee0cdc7b7a2f22d49708c\spring-web-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.15.4\560309fc381f77d4d15c4a4cdaa0db5025c4fd13\jackson-databind-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.15.4\5223ea5a9bf52cdc9c5e537a0e52f2432eaf208b\jackson-annotations-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\13.0\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\annotations-13.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-aop\3.2.4\11aedc0a23c43947608f2122eed08eabe5e2994c\spring-boot-starter-aop-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-jdbc\3.2.4\7dd399e7ba19d62cae32be6e20edac37ff8fcbc0\spring-boot-starter-jdbc-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.hibernate.orm\hibernate-core\6.4.4.Final\5c9decb3c5a70bf7801d41fc32633416c26be069\hibernate-core-6.4.4.Final.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.data\spring-data-jpa\3.2.4\1932f90c487999575b57ad41986de96c8ebf5843\spring-data-jpa-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aspects\6.1.5\202d9da55e24fec2eda80bbc3cd87fbefc0e1256\spring-aspects-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\6.1.5\9ae967f467281c9bb977585ef4d5ea7351704d60\spring-beans-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\6.1.5\6dae1b06ffacbb9abab636be2dbc6acd3b6e5d68\spring-core-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\io.projectreactor\reactor-core\3.6.4\ef683486f29c4bbd1615abc5a83efc6bad8be871\reactor-core-3.6.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jdk8\2.15.4\694777f182334a21bf1aeab1b04cc4398c801f3f\jackson-datatype-jdk8-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jsr310\2.15.4\7de629770a4559db57128d35ccae7d2fddd35db3\jackson-datatype-jsr310-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.module\jackson-module-parameter-names\2.15.4\e654497a08359db2521b69b5f710e00836915d8c\jackson-module-parameter-names-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\3.2.4\b3f481aff8f0775f44d78399c804a8c52d75b971\spring-boot-autoconfigure-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\3.2.4\ccb7cbb30dcf1d91dbbf20a3219a457eead46601\spring-boot-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.annotation\jakarta.annotation-api\2.1.1\48b9bda22b091b1f48b13af03fe36db3be6e1ae3\jakarta.annotation-api-2.1.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-logging\3.2.4\32616f4a33ec0fda0c54aaa67ab10dc78df3fd78\spring-boot-starter-logging-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\2.2\3af797a25458550a16bf89acc8e4ab2b7f2bfce0\snakeyaml-2.2.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-websocket\10.1.19\adf4710fac2471236f8a466ca678cdf7e6a8257c\tomcat-embed-websocket-10.1.19.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-core\10.1.19\3dbbca8acbd4dd6a137c3d6f934a2931512b42ce\tomcat-embed-core-10.1.19.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-el\10.1.19\c61a582c391aca130884a5421deedfe1a96c7415\tomcat-embed-el-10.1.19.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\6.1.5\735d1bd7372d7c53e7b31b4a9c980ce2e0b26424\spring-context-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\6.1.5\a4f596bd3c55b6cec93f0e2e7245dd0bab8afec3\spring-aop-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\6.1.5\7e21cb1c6bbef1509e12d485b75ffc61278d9fa7\spring-expression-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\io.micrometer\micrometer-observation\1.12.4\492deebbd9b8ab23f588428f66578e21af266e01\micrometer-observation-1.12.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.15.4\aebe84b45360debad94f692a4074c6aceb535fa0\jackson-core-2.15.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.aspectj\aspectjweaver\1.9.21\beaabaea95c7f3330f415c72ee0ffe79b51d172f\aspectjweaver-1.9.21.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jdbc\6.1.5\e8617dcddd3377c809b3e62c325fcb923163cb20\spring-jdbc-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.zaxxer\HikariCP\5.0.1\a74c7f0a37046846e88d54f7cb6ea6d565c65f9c\HikariCP-5.0.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.persistence\jakarta.persistence-api\3.1.0\66901fa1c373c6aff65c13791cc11da72060a8d6\jakarta.persistence-api-3.1.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.transaction\jakarta.transaction-api\2.0.1\51a520e3fae406abb84e2e1148e6746ce3f80a1a\jakarta.transaction-api-2.0.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-orm\6.1.5\d2dc2b996680fcc8ae5aea294f0ce6bda5577c7c\spring-orm-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.data\spring-data-commons\3.2.4\c934470822afb9f0751915b229d6fe28ff5e1ac2\spring-data-commons-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-tx\6.1.5\90e95f4c3e30f9ecaef6ba53186ed21afebba618\spring-tx-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.antlr\antlr4-runtime\4.13.0\5a02e48521624faaf5ff4d99afc88b01686af655\antlr4-runtime-4.13.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\2.0.12\48f109a2a6d8f446c794f3e3fa0d86df0cdfa312\slf4j-api-2.0.12.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jcl\6.1.5\896ae3519327731589c6e77521656b50ae32d5b3\spring-jcl-6.1.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.reactivestreams\reactive-streams\1.0.4\3864a1320d97d7b045f729a326e1e077661f31b7\reactive-streams-1.0.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.4.14\d98bc162275134cdf1518774da4a2a17ef6fb94d\logback-classic-1.4.14.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-to-slf4j\2.21.1\d77b2ba81711ed596cd797cc2b5b5bd7409d841c\log4j-to-slf4j-2.21.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.slf4j\jul-to-slf4j\2.0.12\eb5f48f782b41cc881b0bf1fb4d88ae2ff6d5b93\jul-to-slf4j-2.0.12.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\io.micrometer\micrometer-commons\1.12.4\a57f10c78956b38087f97beae66cf14cb8b08d34\micrometer-commons-1.12.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.4.14\4d3c2248219ac0effeb380ed4c5280a80bf395e8\logback-core-1.4.14.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.21.1\74c65e87b9ce1694a01524e192d7be989ba70486\log4j-api-2.21.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-devtools\3.2.4\ccd261700a4ff8e8f629a4d267f0b4f53ca17897\spring-boot-devtools-3.2.4.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.mariadb.jdbc\mariadb-java-client\3.3.3\149f773186f5b7d2e840cfaecf4e3bcdddf7b065\mariadb-java-client-3.3.3.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.github.waffle\waffle-jna\3.3.0\6c1a06b345702bb1dfd77006af926b091bded851\waffle-jna-3.3.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.jboss.logging\jboss-logging\3.5.3.Final\c88fc1d8a96d4c3491f55d4317458ccad53ca663\jboss-logging-3.5.3.Final.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.hibernate.common\hibernate-commons-annotations\6.0.6.Final\77a5f94b56d49508e0ee334751db5b78e5ccd50c\hibernate-commons-annotations-6.0.6.Final.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\io.smallrye\jandex\3.1.2\a6c1c89925c7df06242b03dddb353116ceb9584c\jandex-3.1.2.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.fasterxml\classmate\1.6.0\91affab6f84a2182fce5dd72a8d01bc14346dddd\classmate-1.6.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\net.bytebuddy\byte-buddy\1.14.12\6e37f743dc15a8d7a4feb3eb0025cbc612d5b9e1\byte-buddy-1.14.12.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-runtime\4.0.5\ca84c2a7169b5293e232b9d00d1e4e36d4c3914a\jaxb-runtime-4.0.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.xml.bind\jakarta.xml.bind-api\4.0.2\6cd5a999b834b63238005b7144136379dc36cad2\jakarta.xml.bind-api-4.0.2.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.inject\jakarta.inject-api\2.0.1\4c28afe1991a941d7702fe1362c365f0a8641d1e\jakarta.inject-api-2.0.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.slf4j\jcl-over-slf4j\2.0.12\4462ddec70c0126e580dd0a637cb105a3c7a99ab\jcl-over-slf4j-2.0.12.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\net.java.dev.jna\jna-platform\5.13.0\88e9a306715e9379f3122415ef4ae759a352640d\jna-platform-5.13.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\net.java.dev.jna\jna\5.13.0\1200e7ebeedbe0d10062093f32925a912020e747\jna-5.13.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.github.ben-manes.caffeine\caffeine\3.1.8\24795585df8afaf70a2cd534786904ea5889c047\caffeine-3.1.8.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.checkerframework\checker-qual\3.37.0\ba74746d38026581c12166e164bb3c15e90cc4ea\checker-qual-3.37.0.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-core\4.0.5\7b4b11ea5542eea4ad55e1080b23be436795b3\jaxb-core-4.0.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\jakarta.activation\jakarta.activation-api\2.1.3\fa165bd70cda600368eee31555222776a46b881f\jakarta.activation-api-2.1.3.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.google.errorprone\error_prone_annotations\2.21.1\6d9b10773b5237df178a7b3c1b4208df7d0e7f94\error_prone_annotations-2.21.1.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.eclipse.angus\angus-activation\2.0.2\41f1e0ddd157c856926ed149ab837d110955a9fc\angus-activation-2.0.2.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\txw2\4.0.5\f36a4ef12120a9bb06d766d6a0e54b144fd7ed98\txw2-4.0.5.jar;C:\Users\SmileB\.gradle\caches\modules-2\files-2.1\com.sun.istack\istack-commons-runtime\4.1.2\18ec117c85f3ba0ac65409136afa8e42bc74e739\istack-commons-runtime-4.1.2.jar com.example.study.StudyApplicationKt
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.4)
[16:58:50.118][INFO ][com.example.study.StudyApplicationKt.logStarting:line50] - Starting StudyApplicationKt using Java 20 with PID 19124 (C:\Users\SmileB\Desktop\kakaopay\SpringKotlinAPI\study\build\classes\kotlin\main started by SmileB in C:\Users\SmileB\Desktop\kakaopay\SpringKotlinAPI)
[16:58:50.120][INFO ][com.example.study.StudyApplicationKt.logStartupProfileInfo:line654] - No active profile set, falling back to 1 default profile: "default"
[16:58:50.209][INFO ][org.springframework.boot.devtools.env.DevToolsPropertyDefaultsPostProcessor.logTo:line252] - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
[16:58:50.210][INFO ][org.springframework.boot.devtools.env.DevToolsPropertyDefaultsPostProcessor.logTo:line252] - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
[16:58:51.462][INFO ][org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn:line139] - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
[16:58:51.661][INFO ][org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn:line208] - Finished Spring Data repository scanning in 186 ms. Found 1 JPA repository interface.
[16:58:52.564][INFO ][org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize:line109] - Tomcat initialized with port 9999 (http)
[16:58:52.586][INFO ][org.apache.catalina.core.StandardService.log:line173] - Starting service [Tomcat]
[16:58:52.586][INFO ][org.apache.catalina.core.StandardEngine.log:line173] - Starting Servlet engine: [Apache Tomcat/10.1.19]
[16:58:52.647][INFO ][org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].log:line173] - Initializing Spring embedded WebApplicationContext
[16:58:52.648][INFO ][org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.prepareWebApplicationContext:line296] - Root WebApplicationContext: initialization completed in 2436 ms
[16:58:52.885][INFO ][org.hibernate.jpa.internal.util.LogHelper.logPersistenceUnitInformation:line31] - HHH000204: Processing PersistenceUnitInfo [name: default]
[16:58:52.987][INFO ][org.hibernate.Version.logVersion:line44] - HHH000412: Hibernate ORM core version 6.4.4.Final
[16:58:53.038][INFO ][org.hibernate.cache.internal.RegionFactoryInitiator.initiateService:line50] - HHH000026: Second-level cache disabled
[16:58:53.346][INFO ][org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo.addTransformer:line87] - No LoadTimeWeaver setup: ignoring JPA class transformer
[16:58:53.378][INFO ][com.zaxxer.hikari.HikariDataSource.getConnection:line110] - HikariPool-1 - Starting...
[16:58:53.539][INFO ][com.zaxxer.hikari.pool.HikariPool.checkFailFast:line565] - HikariPool-1 - Added connection org.mariadb.jdbc.Connection@40d93b65
[16:58:53.541][INFO ][com.zaxxer.hikari.HikariDataSource.getConnection:line123] - HikariPool-1 - Start completed.
[16:58:53.623][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(12, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@55c69ddb) replaced previous registration(org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@11eafa01)
[16:58:53.623][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(-9, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@69820055) replaced previous registration(org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@2265fbce)
[16:58:53.623][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(-3, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@43ac821c) replaced previous registration(org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@550429a)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(4003, org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@7ca97acd) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@719f551d)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(4001, org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@56048550) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@51475998)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(4002, org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@668f3e6f) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@6d33a81e)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(2004, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@1f6f8eed) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@748f9f01)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(2005, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@6b6cabb9) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@1bef9d92)
[16:58:53.624][DEBUG][org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry.addDescriptor:line64] - addDescriptor(2011, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@789460e4) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@70eb8f60)
[16:58:54.423][INFO ][org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator.initiateService:line58] - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
[16:58:54.439][DEBUG][org.hibernate.SQL.logStatement:line135] -
drop table if exists wordcount
[16:58:54.511][DEBUG][org.hibernate.SQL.logStatement:line135] -
create table wordcount (
cnt integer not null,
word varchar(255) not null,
primary key (word)
) engine=InnoDB
[16:58:54.528][INFO ][org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.buildNativeEntityManagerFactory:line437] - Initialized JPA EntityManagerFactory for persistence unit 'default'
[16:58:55.672][INFO ][org.springframework.boot.devtools.autoconfigure.OptionalLiveReloadServer.startServer:line59] - LiveReload server is running on port 35729
[16:58:55.716][INFO ][org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start:line241] - Tomcat started on port 9999 (http) with context path ''
[16:58:55.730][INFO ][com.example.study.StudyApplicationKt.logStarted:line56] - Started StudyApplicationKt in 6.302 seconds (process running for 7.028)
이상없이 동작하니 Postman으로 Exception이 동작하는지 확인한다.
정상적으로 동작하는 JSON에서 query를 제거해서 Send를 눌러보면


trace에 query parameter required라는것은 보이지만, status 500에러가 뜨는것은 코드가 잘못돼서 발생하는 코드이다.
확인 해보니 blog와 core를 study 패키지 안에 넣어줘야 blog service에있는
InvalidInputException에 messge를 던져줄때, InvalidInputException을 참조, 찾지 못해서 발생한 에러였다.

그래서 아래와 같이 response 폴더위치를 옮겨주고 서버를 재시작 후 postman으로 테스트를 다시해보면,
Main
ㄴ Kotlin
ㄴ study
ㄴ blog
ㄴ controller
ㄴ dto
ㄴ entity
ㄴ response
ㄴ service //수정됨, 예외처리
ㄴ StudyApplication.kt
//추가된 내용
ㄴ core
ㄴ exception
ㄴ CustomExceptionHandler
ㄴ InvalidInputException
ㄴ response
ㄴ ErrorResponse
query가 비었을때 출력되는 부분으로, 400에러 코드로 bad request도 정상적으로 나온다.
qeary가 비었을때

sort가 receny, accuracy 가 아닐때
그리고 sort도 recency, accuracy 두개가 아닌 다른 값이 들어왔을때,

sort parameter는 accuracy 또는 recency 둘중에 하나를 골라달라는 메시지를 받을수 있다.
이어서
page가 1 미만일때

page가 50 초과일때

4가지 사항 모두 정상적으로 에러 값을 반환 받을수 있었다.