From 4f31848531a70b72c9877a891f46420bcaf63c61 Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 02:19:11 +0900 Subject: [PATCH 1/7] =?UTF-8?q?chore:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vacgom/backend/{member/domain => domain/member}/Member.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/kotlin/com/vacgom/backend/{member/domain => domain/member}/Member.kt (87%) diff --git a/src/main/kotlin/com/vacgom/backend/member/domain/Member.kt b/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt similarity index 87% rename from src/main/kotlin/com/vacgom/backend/member/domain/Member.kt rename to src/main/kotlin/com/vacgom/backend/domain/member/Member.kt index f0f339e..eb7fe62 100644 --- a/src/main/kotlin/com/vacgom/backend/member/domain/Member.kt +++ b/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt @@ -1,4 +1,4 @@ -package com.vacgom.backend.member.domain +package com.vacgom.backend.domain.member import com.vacgom.backend.global.auditing.BaseEntity import jakarta.persistence.* From add0b23075c3da7dbd55445351058c3dbac92243 Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 02:33:50 +0900 Subject: [PATCH 2/7] =?UTF-8?q?chore:=20GIT=5FTOKEN=20=EC=93=B0=EA=B8=B0?= =?UTF-8?q?=20=EA=B6=8C=ED=95=9C=20=EB=B6=80=EC=A1=B1=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EC=98=A4=ED=86=A0=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=EC=96=B4=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/PULL_REQUEST_TEMPLATE.md | 7 ++----- .github/workflows/CI.yml | 21 ++++----------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6c94357..1dd61da 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,16 +1,13 @@ ## PULL REQUEST -### πŸŽ‹ μž‘μ—… 쀑인 브랜치 +### πŸŽ‹ Issue Ticket - ### πŸ”‘ μ£Όμš” μž‘μ—…μ‚¬ν•­ - ### 🏞 (Optional) μ°Έκ³  자료 -- μŠ€ν¬λ¦°μƒ·μ„ μ²¨λΆ€ν•΄μ£Όμ„Έμš”. - -### κ΄€λ ¨ 이슈 - ### κΌ­ 확인해 μ£Όμ„Έμš”!! -- +- diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a96161b..ff5d6a4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,4 +1,4 @@ -name: λΉŒλ“œ ν…ŒμŠ€νŠΈ / 리뷰어 ν• λ‹Ή +name: λΉŒλ“œ ν…ŒμŠ€νŠΈ on: pull_request: @@ -8,12 +8,12 @@ on: - 'master' jobs: - build_and_review_assign: - name: "[CI] Check Build/Testcases and Assign Reviewer" + build: + name: "[CI] Check Build" runs-on: ubuntu-latest steps: - - name: (Set Up) checkout + - name: Checkout code uses: actions/checkout@v3 with: token: ${{ secrets.GIT_TOKEN }} @@ -27,16 +27,3 @@ jobs: - name: (Set Up) Grant Execute permission for gradlew run: chmod 777 gradlew - - - name: (Build) Build with Gradle - id: build - run: ./gradlew test -i - - - name: (Assign Reviewer) - if: steps.build.outcome == 'success' - uses: hkusu/review-assign-action@v1 - with: - assignees: ${{ github.actor }} - reviewers: HyungJu, h-beeen - ready-comment: 'μ½”λ“œ 리뷰 μš”μ²­ν•©λ‹ˆλ‹€ πŸ™† ' - merged-comment: 'μ„±κ³΅μ μœΌλ‘œ Merge λ˜μ—ˆμŠ΅λ‹ˆλ‹€. Shout out to :wink:' From c93096dd934cc525f5d18ff30e3ca54290d5da7d Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 02:35:35 +0900 Subject: [PATCH 3/7] =?UTF-8?q?chore:=20PR=20Template=EC=97=90=20=EC=84=9C?= =?UTF-8?q?=EB=B8=8C=EB=AA=A8=EB=93=88=20=EA=B4=80=EB=A0=A8=20Noti=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/PULL_REQUEST_TEMPLATE.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1dd61da..1a0e6de 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,5 +9,11 @@ ### 🏞 (Optional) μ°Έκ³  자료 - +### (μ€‘μš”) μ„œλΈŒλͺ¨λ“ˆμ΄ μˆ˜μ •λ˜μ—ˆλ‚˜μš”? +- κΈ°μ‘΄ 컀밋 : +- λ³€κ²½ 컀밋 : +- λ³€κ²½ 사항 : +- [] ν•΄λ‹Ή μ„œλΈŒλͺ¨λ“ˆ 변경사항이 PR에 잘 λ°˜μ˜λ˜μ—ˆλ‚˜μš”? + ### κΌ­ 확인해 μ£Όμ„Έμš”!! - From 6cc890feccb970761398db4cf2019a6ad0f853ac Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 03:42:01 +0900 Subject: [PATCH 4/7] feat: Global Exception Handling --- .../global/exception/ApiExceptionHandler.kt | 55 +++++++++++++++++++ .../exception/ApiExceptionHandlingFilter.kt | 45 +++++++++++++++ .../exception/error/BusinessException.kt | 6 ++ .../global/exception/error/ErrorCode.kt | 9 +++ .../global/exception/error/ErrorResponse.kt | 41 ++++++++++++++ .../global/exception/error/GlobalError.kt | 12 ++++ .../backend/global/logger/CommonLogger.kt | 7 +++ 7 files changed, 175 insertions(+) create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandler.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/error/BusinessException.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorCode.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorResponse.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/exception/error/GlobalError.kt create mode 100644 src/main/kotlin/com/vacgom/backend/global/logger/CommonLogger.kt diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandler.kt b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandler.kt new file mode 100644 index 0000000..36f6c8a --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandler.kt @@ -0,0 +1,55 @@ +package com.vacgom.backend.global.exception + +import com.vacgom.backend.global.exception.error.BusinessException +import com.vacgom.backend.global.exception.error.ErrorCode +import com.vacgom.backend.global.exception.error.ErrorResponse +import com.vacgom.backend.global.exception.error.GlobalError +import com.vacgom.backend.global.logger.CommonLogger +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.MethodArgumentNotValidException +import org.springframework.web.bind.MissingServletRequestParameterException +import org.springframework.web.bind.annotation.ExceptionHandler +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestControllerAdvice + +@RestControllerAdvice +class ApiExceptionHandler { + companion object : CommonLogger(); + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MethodArgumentNotValidException::class) + fun handleMethodArgumentNotValidException(ex: MethodArgumentNotValidException): ErrorResponse? { + return ErrorResponse(ex.fieldErrors) + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MissingServletRequestParameterException::class) + fun missingServletRequestParameterException(): ErrorResponse? { + return ErrorResponse(GlobalError.INVALID_REQUEST_PARAM) + } + + @ExceptionHandler(BusinessException::class) + fun handleBusinessException( + exception: BusinessException + ): ResponseEntity { + logBusinessException(exception) + return convert(exception.errorCode) + } + + private fun convert( + errorCode: ErrorCode + ): ResponseEntity { + return ResponseEntity + .status(errorCode.status) + .body(ErrorResponse(errorCode)) + } + + private fun logBusinessException(exception: BusinessException) { + if (exception.errorCode.status.is5xxServerError) { + log.error("", exception) + } else { + log.error("Error Message = {}", exception.message) + } + } +} diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt new file mode 100644 index 0000000..e078468 --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt @@ -0,0 +1,45 @@ +package com.vacgom.backend.global.exception + +import com.fasterxml.jackson.databind.ObjectMapper +import com.vacgom.backend.global.exception.error.BusinessException +import com.vacgom.backend.global.exception.error.ErrorResponse +import jakarta.servlet.FilterChain +import jakarta.servlet.ServletException +import jakarta.servlet.http.HttpServletRequest +import jakarta.servlet.http.HttpServletResponse +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.stereotype.Component +import org.springframework.web.filter.OncePerRequestFilter +import java.io.IOException + + +@Component +class ApiExceptionHandlingFilter( + private val om: ObjectMapper +) : OncePerRequestFilter() { + + @Throws(ServletException::class, IOException::class) + override fun doFilterInternal( + request: HttpServletRequest, + response: HttpServletResponse, + chain: FilterChain + ) { + try { + chain.doFilter(request, response) + } catch (exception: BusinessException) { + setErrorResponse(response, exception) + } + } + + private fun setErrorResponse( + response: HttpServletResponse, + exception: BusinessException + ) = try { + response.contentType = MediaType.APPLICATION_JSON_VALUE + response.status = HttpStatus.UNAUTHORIZED.value() + om.writeValue(response.outputStream, ErrorResponse(exception.errorCode)) + } catch (ex: IOException) { + throw RuntimeException(ex) + } +} diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/error/BusinessException.kt b/src/main/kotlin/com/vacgom/backend/global/exception/error/BusinessException.kt new file mode 100644 index 0000000..638ee2b --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/error/BusinessException.kt @@ -0,0 +1,6 @@ +package com.vacgom.backend.global.exception.error + + +class BusinessException( + val errorCode: ErrorCode +) : RuntimeException(errorCode.message) diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorCode.kt b/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorCode.kt new file mode 100644 index 0000000..550d1dc --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorCode.kt @@ -0,0 +1,9 @@ +package com.vacgom.backend.global.exception.error + +import org.springframework.http.HttpStatus + +interface ErrorCode { + val message: String + val status: HttpStatus + val code: String +} diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorResponse.kt b/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorResponse.kt new file mode 100644 index 0000000..4b7b4a0 --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/error/ErrorResponse.kt @@ -0,0 +1,41 @@ +package com.vacgom.backend.global.exception.error + +import org.springframework.validation.FieldError +import java.time.LocalDateTime + +data class ErrorResponse( + val timeStamp: String = LocalDateTime.now().toString(), + val errorCode: String, + val errorMessage: String, + val details: Any? = null +) { + constructor( + errorCode: ErrorCode + ) : this( + errorCode = errorCode.code, + errorMessage = errorCode.message + ) + + constructor( + errorCode: ErrorCode, + details: Any? + ) : this( + errorCode = errorCode.code, + errorMessage = errorCode.message, + details = details + ) + + constructor( + fieldError: FieldError? + ) : this( + errorCode = fieldError?.code ?: "", + errorMessage = fieldError?.defaultMessage ?: "" + ) + + constructor(fieldErrors: List) : this( + GlobalError.INVALID_REQUEST_PARAM, + fieldErrors.associate { + it.field to (it.defaultMessage ?: "null") + } + ) +} diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/error/GlobalError.kt b/src/main/kotlin/com/vacgom/backend/global/exception/error/GlobalError.kt new file mode 100644 index 0000000..432f9c5 --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/exception/error/GlobalError.kt @@ -0,0 +1,12 @@ +package com.vacgom.backend.global.exception.error + +import org.springframework.http.HttpStatus + +enum class GlobalError( + override val message: String, + override val status: HttpStatus, + override val code: String +) : ErrorCode { + GLOBAL_NOT_FOUND("λ¦¬μ†ŒμŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.", HttpStatus.NOT_FOUND, "G_001"), + INVALID_REQUEST_PARAM("μš”μ²­ νŒŒλΌλ―Έν„°κ°€ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.", HttpStatus.BAD_REQUEST, "G_002"); +} diff --git a/src/main/kotlin/com/vacgom/backend/global/logger/CommonLogger.kt b/src/main/kotlin/com/vacgom/backend/global/logger/CommonLogger.kt new file mode 100644 index 0000000..0d8e1c9 --- /dev/null +++ b/src/main/kotlin/com/vacgom/backend/global/logger/CommonLogger.kt @@ -0,0 +1,7 @@ +package com.vacgom.backend.global.logger + +import org.slf4j.LoggerFactory + +abstract class CommonLogger { + val log = LoggerFactory.getLogger(this.javaClass)!! +} From dd8a928298825e725cf86f5127e698cae8196226 Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 03:42:14 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20member=20->=20user=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/vacgom/backend/domain/member/Member.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt b/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt index eb7fe62..de0538c 100644 --- a/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt +++ b/src/main/kotlin/com/vacgom/backend/domain/member/Member.kt @@ -4,13 +4,18 @@ import com.vacgom.backend.global.auditing.BaseEntity import jakarta.persistence.* @Entity -@Table(name = "t_user") -class User( - val nickname: String -) : BaseEntity() { +@Table(name = "t_member") +class Member(nickname: String) : BaseEntity() { @Id - @Column(name = "user_id") + @Column(name = "member_id") @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long? = null + + @Column(name = "nickname") + val nickname: String + + init { + this.nickname = nickname + } } From 4a05c138555889d51d5b233673d80e16cdef173d Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 03:45:40 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20CI=20pipeline=EC=97=90=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=88=84=EB=9D=BD?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ff5d6a4..680093b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,15 +1,15 @@ -name: λΉŒλ“œ ν…ŒμŠ€νŠΈ +name: ν…ŒμŠ€νŠΈ μ½”λ“œ 및 λΉŒλ“œ on: pull_request: - types: [opened, synchronize, closed] + types: [ opened, synchronize, closed ] branches: - 'develop' - 'master' jobs: - build: - name: "[CI] Check Build" + test: + name: "[CI] Check Tests" runs-on: ubuntu-latest steps: @@ -19,11 +19,17 @@ jobs: token: ${{ secrets.GIT_TOKEN }} submodules: true - - name: (Set Up) Set up JDK 17 + - name: Setup Java 17 uses: actions/setup-java@v3 with: java-version: '17' - distribution: 'temurin' + distribution: 'adopt' - - name: (Set Up) Grant Execute permission for gradlew - run: chmod 777 gradlew + - name: Update Git submodules + run: git submodule update --remote --recursive + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Test with Gradle + run: ./gradlew test From 9d1f4c0efbe7d443e9472516b8d7a8b17c205b3e Mon Sep 17 00:00:00 2001 From: Haebin Date: Fri, 15 Mar 2024 04:02:35 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EC=B6=95=EC=95=BD=ED=98=95=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/global/exception/ApiExceptionHandlingFilter.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt index e078468..37cb8e1 100644 --- a/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt +++ b/src/main/kotlin/com/vacgom/backend/global/exception/ApiExceptionHandlingFilter.kt @@ -39,7 +39,7 @@ class ApiExceptionHandlingFilter( response.contentType = MediaType.APPLICATION_JSON_VALUE response.status = HttpStatus.UNAUTHORIZED.value() om.writeValue(response.outputStream, ErrorResponse(exception.errorCode)) - } catch (ex: IOException) { - throw RuntimeException(ex) + } catch (exception: IOException) { + throw RuntimeException(exception) } }