diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8dbd3887..c6b09738 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -28,6 +28,7 @@ jobs: echo "${{ secrets.TEST_PROPERTIES }}" | base64 --decode > src/test/resources/application.yml mkdir -p src/main/resources/credential echo "${{ secrets.FCM_KEY }}" | base64 --decode > src/main/resources/credential/fcm-service-key.json + echo "${{ secrets.GRADLE }}" | base64 --decode > ./gradle.properties - name: Grant execute permission for gradlew run: | diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index f70aef08..3ac533e2 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -30,6 +30,7 @@ jobs: echo "${{ secrets.TEST_PROPERTIES }}" | base64 --decode > src/test/resources/application.yml mkdir -p src/main/resources/credential echo "${{ secrets.FCM_KEY }}" | base64 --decode > src/main/resources/credential/fcm-service-key.json + echo "${{ secrets.GRADLE }}" | base64 --decode > ./gradle.properties - name: Grant execute permission for gradlew diff --git a/build.gradle b/build.gradle index ccb006b9..a502d7d1 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'org.springframework.boot' version '3.2.1' id 'io.spring.dependency-management' version '1.1.4' id 'org.asciidoctor.jvm.convert' version '3.3.2' + id "io.sentry.jvm.gradle" version "4.4.1" } group = 'com.yanolja' @@ -12,6 +13,9 @@ java { sourceCompatibility = '17' } +generateSentryBundleIdJava.dependsOn compileJava +sentryCollectSourcesJava.dependsOn compileTestJava + configurations { compileOnly { extendsFrom annotationProcessor @@ -23,6 +27,17 @@ repositories { mavenCentral() } +sentry { + // Generates a JVM (Java, Kotlin, etc.) source bundle and uploads your source code to Sentry. + // This enables source context, allowing you to see your source + // code as part of your stack traces in Sentry. + includeSourceContext = true + + org = "eb256c3f1cf9" + projectName = "java-spring-boot" + authToken = System.getenv("SENTRY_AUTH_TOKEN") +} + ext { set('snippetsDir', file("build/generated-snippets")) } @@ -102,6 +117,8 @@ dependencies { // restdocs testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' + + implementation 'io.sentry:sentry-spring-boot-starter-jakarta:7.8.0' } def querydslDir = "src/main/generated" diff --git a/src/main/java/com/yanolja/scbj/global/exception/GlobalRestControllerAdvice.java b/src/main/java/com/yanolja/scbj/global/exception/GlobalRestControllerAdvice.java index 3333afa2..9d9931e7 100644 --- a/src/main/java/com/yanolja/scbj/global/exception/GlobalRestControllerAdvice.java +++ b/src/main/java/com/yanolja/scbj/global/exception/GlobalRestControllerAdvice.java @@ -5,6 +5,7 @@ import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.SignatureException; +import io.sentry.Sentry; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; @@ -17,12 +18,14 @@ public class GlobalRestControllerAdvice { @ExceptionHandler public ResponseEntity> bindException(BindException e) { + Sentry.captureException(e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(ResponseDTO.res(e.getBindingResult().getAllErrors().get(0).getDefaultMessage())); } @ExceptionHandler public ResponseEntity> applicationException(ApplicationException e) { + Sentry.captureException(e); return ResponseEntity.status(e.getErrorCode().getHttpStatus()) .body(ResponseDTO.res(e.getMessage())); @@ -30,6 +33,7 @@ public ResponseEntity> applicationException(ApplicationExcep @ExceptionHandler public ResponseEntity> expiredJWTException(ExpiredJwtException e) { + Sentry.captureException(e); return ResponseEntity.status(ErrorCode.EXPIRED_TOKEN.getHttpStatus()) .body(ResponseDTO.res(ErrorCode.EXPIRED_TOKEN.getSimpleMessage())); } @@ -37,12 +41,14 @@ public ResponseEntity> expiredJWTException(ExpiredJwtExcepti @ExceptionHandler({MalformedJwtException.class, SignatureException.class, UnsupportedJwtException.class}) public ResponseEntity> invalidJWTException(Exception e) { + Sentry.captureException(e); return ResponseEntity.status(ErrorCode.INVALID_TOKEN.getHttpStatus()) .body(ResponseDTO.res(ErrorCode.INVALID_TOKEN.getSimpleMessage())); } @ExceptionHandler public ResponseEntity> ValidationException(MethodValidationException e) { + Sentry.captureException(e); return ResponseEntity.badRequest().body(ResponseDTO.res(e.getMessage())); } } \ No newline at end of file