-
Notifications
You must be signed in to change notification settings - Fork 0
[fix] 예외 처리 개선 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix] 예외 처리 개선 #17
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ name: CI / CD | |
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| branches: [fix/#16-exception-handling-fix] | ||
|
|
||
| jobs: | ||
| CI: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,22 +6,20 @@ | |
| import com.gcp.domain.discord.repository.DiscordUserRepository; | ||
| import com.gcp.domain.gcp.dto.ProjectZoneDto; | ||
| import com.gcp.domain.gcp.repository.GcpProjectRepository; | ||
| import com.google.auth.oauth2.GoogleCredentials; | ||
| import com.google.cloud.compute.v1.Project; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.SneakyThrows; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.checkerframework.checker.units.qual.A; | ||
|
|
||
| import org.json.JSONArray; | ||
| import org.json.JSONObject; | ||
| import org.springframework.http.*; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.web.client.HttpClientErrorException; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.*; | ||
|
|
||
| @Service | ||
|
|
@@ -54,8 +52,8 @@ public String startVM(String userId, String guildId, String vmName) { | |
|
|
||
| return "🚀 `" + vmName + "` VM을 실행했습니다!"; | ||
| } catch (Exception e) { | ||
| log.error("VM 실행 오류", e); | ||
| return "❌ `" + vmName + "` VM 실행 실패!"; | ||
| log.error("❌ VM 시작 오류", e); | ||
| throw new RuntimeException("Compute API (start) 호출 도중 에러 발생: ", e); | ||
| } | ||
|
Comment on lines
+55
to
57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 중복적인 모든 메서드에서 동일한 패턴으로 예외를 잡아
서비스 전용 Also applies to: 76-79, 102-105, 169-172, 181-183, 198-204, 227-230, 268-271, 373-375, 418-420, 460-461, 486-487 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
|
|
@@ -77,7 +75,7 @@ public String stopVM(String userId, String guildId, String vmName) { | |
| return "🛑 `" + vmName + "` VM을 중지했습니다!"; | ||
| } catch (Exception e) { | ||
| log.error("❌ VM 중지 오류", e); | ||
| return "❌ `" + vmName + "` VM 중지 실패!"; | ||
| throw new RuntimeException("Compute API (stop) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -103,7 +101,7 @@ public String getInstanceId(String userId, String guildId, String vmName, String | |
|
|
||
| } catch (Exception e) { | ||
| log.error("❌ instance_id 조회 실패", e); | ||
| return null; | ||
| throw new RuntimeException("Compute API (인스턴스 ID 조회) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -118,7 +116,7 @@ public List<String> getVmLogs(String userId, String guildId, String vmName) { | |
|
|
||
| String vmId = getInstanceId(userId, guildId, vmName, ZONE); | ||
| if (vmId == null){ | ||
| return List.of("❌ VM 인스턴스를 찾을 수 없습니다!"); | ||
| throw new RuntimeException("현재 보유 중인 VM이 없습니다."); | ||
| } | ||
|
|
||
| String filter = String.format( | ||
|
|
@@ -170,10 +168,7 @@ public List<String> getVmLogs(String userId, String guildId, String vmName) { | |
|
|
||
| } catch (Exception e) { | ||
| log.error("❌ 로그 조회 오류", e); | ||
| List<String> errorMessage = new ArrayList<>(); | ||
| errorMessage.add("❌ 로그 조회 실패!"); | ||
|
|
||
| return errorMessage; | ||
| throw new RuntimeException("Logging API 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -184,45 +179,55 @@ public String getEstimatedCost() { | |
| return "💰 예상 비용: " + response; | ||
| } catch (Exception e) { | ||
| log.error("❌ 비용 조회 오류", e); | ||
| return "❌ 비용 조회 실패!"; | ||
| throw new RuntimeException("CloudBilling API 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
| @SneakyThrows | ||
| public List<Map<String, String>> getVmList(String userId, String guildId) { | ||
| String url = String.format("https://compute.googleapis.com/compute/v1/projects/%s/zones/%s/instances", | ||
| PROJECT_ID, ZONE); | ||
| try { | ||
| String url = String.format("https://compute.googleapis.com/compute/v1/projects/%s/zones/%s/instances", | ||
| PROJECT_ID, ZONE); | ||
|
|
||
| String accessToken = discordUserRepository.findAccessTokenByUserIdAndGuildId(userId, guildId).orElseThrow(); | ||
| HttpHeaders headers = new HttpHeaders(); | ||
| headers.set("Authorization", "Bearer " + accessToken); | ||
| headers.setContentType(MediaType.APPLICATION_JSON); | ||
| String accessToken = discordUserRepository.findAccessTokenByUserIdAndGuildId(userId, guildId).orElseThrow(); | ||
| HttpHeaders headers = new HttpHeaders(); | ||
| headers.set("Authorization", "Bearer " + accessToken); | ||
| headers.setContentType(MediaType.APPLICATION_JSON); | ||
|
|
||
| HttpEntity<String> entity = new HttpEntity<>(null, headers); | ||
| ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); | ||
| HttpEntity<String> entity = new HttpEntity<>(null, headers); | ||
| ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); | ||
|
|
||
| return parseVmResponse(response.getBody()); | ||
| return parseVmResponse(response.getBody()); | ||
| } catch (Exception e){ | ||
| log.error("❌ VM 목록 조회 실패", e); | ||
| throw new RuntimeException("Compute API (인스턴스 목록 조회) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
| public List<String> getProjectIds(String userId, String guildId) { | ||
| String url = "https://cloudresourcemanager.googleapis.com/v1/projects"; | ||
| String accessToken = discordUserRepository.findAccessTokenByUserIdAndGuildId(userId, guildId).orElseThrow(); | ||
| try { | ||
| String url = "https://cloudresourcemanager.googleapis.com/v1/projects"; | ||
| String accessToken = discordUserRepository.findAccessTokenByUserIdAndGuildId(userId, guildId).orElseThrow(); | ||
|
|
||
| HttpHeaders headers = new HttpHeaders(); | ||
| headers.setBearerAuth(accessToken); | ||
| headers.setContentType(MediaType.APPLICATION_JSON); | ||
| HttpHeaders headers = new HttpHeaders(); | ||
| headers.setBearerAuth(accessToken); | ||
| headers.setContentType(MediaType.APPLICATION_JSON); | ||
|
|
||
| HttpEntity<String> entity = new HttpEntity<>(null, headers); | ||
| ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); | ||
| HttpEntity<String> entity = new HttpEntity<>(null, headers); | ||
| ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); | ||
|
|
||
| JSONObject json = new JSONObject(response.getBody()); | ||
| JSONArray projects = json.getJSONArray("projects"); | ||
| JSONObject json = new JSONObject(response.getBody()); | ||
| JSONArray projects = json.getJSONArray("projects"); | ||
|
|
||
| List<String> projectIds = new ArrayList<>(); | ||
| for (int i = 0; i < projects.length(); i++) { | ||
| projectIds.add(projects.getJSONObject(i).getString("projectId")); | ||
| List<String> projectIds = new ArrayList<>(); | ||
| for (int i = 0; i < projects.length(); i++) { | ||
| projectIds.add(projects.getJSONObject(i).getString("projectId")); | ||
| } | ||
| return projectIds; | ||
| } catch (Exception e) { | ||
| log.error("❌ 프로젝트 ID 조회 중 에러 발생", e); | ||
| throw new RuntimeException("CloudResourceManager API 호출 도중 에러 발생: ", e); | ||
| } | ||
| return projectIds; | ||
| } | ||
|
|
||
| public List<ProjectZoneDto> getActiveInstanceZones(String userId, String guildId) { | ||
|
|
@@ -261,7 +266,8 @@ public List<ProjectZoneDto> getActiveInstanceZones(String userId, String guildId | |
| activeZones.add(dto); | ||
|
|
||
| } catch (Exception e) { | ||
| log.warn("프로젝트 Zone 조회 실패 {}: {}", projectId, e.getMessage()); | ||
| log.warn("❌ 프로젝트 Zone 조회 실패 {}", projectId, e); | ||
| throw new RuntimeException("Compute API (VM Zone 조회) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -365,7 +371,7 @@ public String createVM(String userId, String guildId, String vmName, String mach | |
| ); | ||
| } catch (Exception e) { | ||
| log.error("❌ VM 생성 오류", e); | ||
| return "❌ `" + vmName + "` VM 생성 실패!"; | ||
| throw new RuntimeException("Compute API (인스턴스 생성) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
| public List<Map<String, Object>> getFirewallRules(String userId, String guildId) { | ||
|
|
@@ -410,7 +416,7 @@ public List<Map<String, Object>> getFirewallRules(String userId, String guildId) | |
|
|
||
| } catch (Exception e) { | ||
| log.error("❌ 방화벽 규칙 조회 오류", e); | ||
| return List.of(Map.of("error", "방화벽 규칙 조회 실패")); | ||
| throw new RuntimeException("Compute API (방화벽 규칙 조회) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
| public String createFirewallRule(String userId, String guildId, int port, List<String> sourceRanges) { | ||
|
|
@@ -451,7 +457,7 @@ public String createFirewallRule(String userId, String guildId, int port, List<S | |
| return "⚠️ 이미 포트 " + port + " 에 대한 방화벽 규칙이 존재합니다."; | ||
| } catch (Exception e) { | ||
| log.error("❌ 방화벽 규칙 생성 실패", e); | ||
| return "❌ 방화벽 규칙 생성 중 오류가 발생했습니다."; | ||
| throw new RuntimeException("Compute API (방화벽 규칙 생성) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -477,7 +483,7 @@ public String deleteFirewallRule(String userId, String guildId, int port) { | |
| return "⚠️ 포트 " + port + " 에 대한 방화벽 규칙이 존재하지 않습니다."; | ||
| } catch (Exception e) { | ||
| log.error("❌ 방화벽 규칙 삭제 실패", e); | ||
| return "❌ 방화벽 규칙 삭제 중 오류가 발생했습니다."; | ||
| throw new RuntimeException("Compute API (방화벽 규칙 삭제) 호출 도중 에러 발생: ", e); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deferReply() 이후 오류 응답 방식 오류
event.deferReply()호출 후에는event.reply()를 다시 사용할 수 없습니다. 예외 발생 시또는
editOriginal()로 응답을 수정해야 합니다. 동일 패턴이firewall-list등 다른 커맨드에도 있으니 함께 수정해 주세요.🤖 Prompt for AI Agents