Project

[졸업프로젝트] Failed to load resource: the server responded with a status of 500

메델 2023. 6. 18. 22:35

[문제 상황]

'getPicture' 메소드는 요약, 번역, 그리고 이미지 생성을 거쳐 이미지 URL을 반환한다. 요청시, 이 메소드가 정상적으로 처리될 때도 있었지만 일부 500 에러가 발생하였다.

 

[해결 방법]

외부 서비스 호출 시 재시도 로직을 추가해주었다. 일시적인 연결 문제로 예외가 발생한 경우, 1초 대기 후 재시도를 할 수 있게 getPicture()을 수정해 주었다.

 

[이전 코드]

    @GetMapping("/{diary_id}/picture")
    public ResponseEntity<?> getPicture(@PathVariable Long diary_id) {
        // 요약 및 번역
        String summary = clovaSummaryService.summarizeDiary(diary_id);
        String engSummary = papagoTranslationService.translateSummary(diary_id);

        diaryService.setSummary(diary_id, summary, engSummary);

        String imageUrl = stablediffusionService.getTextToImage(diary_id);

        Map<String, Object> response = new HashMap<>();
        response.put("imageUrl", imageUrl);

        return new ResponseEntity<>(response, HttpStatus.OK);
    }

 

[수정 코드]

    @GetMapping("/{diary_id}/picture")
    public ResponseEntity<?> getPicture(@PathVariable Long diary_id) {
        int maxAttempts = 3; // 최대 재시도 횟수
        int attempts = 0;

        while (attempts < maxAttempts) {
            try {
                // 요약 및 번역
                String summary = clovaSummaryService.summarizeDiary(diary_id);
                String engSummary = papagoTranslationService.translateSummary(diary_id);

                diaryService.setSummary(diary_id, summary, engSummary);

                String imageUrl = stablediffusionService.getTextToImage(diary_id);

                Map<String, Object> response = new HashMap<>();
                response.put("imageUrl", imageUrl);

                return new ResponseEntity<>(response, HttpStatus.OK);
            } catch (WebClientRequestException e) {
                // 재시도 로직을 위해 예외 처리
                attempts++;
                if (attempts >= maxAttempts) {
                    // 최대 재시도 횟수를 초과한 경우
                    return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
                }
                // 일시적인 연결 문제로 예외가 발생한 경우, 대기 후 재시도
                try {
                    Thread.sleep(1000); // 1초 대기 후 재시도
                } catch (InterruptedException ex) {
                    // 대기 도중 인터럽트가 발생한 경우 예외 처리
                    Thread.currentThread().interrupt();
                    return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            } catch (Exception e) {
                // 다른 예외가 발생한 경우
                return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }

        // 최대 재시도 횟수를 초과한 경우
        return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
    }

 

 

[2차 수정 코드 - 예외처리 개선]

    @GetMapping("/{diary_id}/picture/paint")
    public ResponseEntity<?> getPictureV1(@PathVariable Long diary_id) {
        return getPictureResponse(diary_id, "V1");
    }


    @GetMapping("/{diary_id}/picture/pencil")
    public ResponseEntity<?> getPictureV2(@PathVariable Long diary_id) {
        return getPictureResponse(diary_id, "V2");
    }

    private ResponseEntity<?> getPictureResponse(Long diary_id, String version) {
        int maxAttempts = 10; // 최대 재시도 횟수
        int attempts = 0;

        while (attempts < maxAttempts) {
            try {
                String summary = clovaSummaryService.summarizeDiary(diary_id);
                String engSummary = papagoTranslationService.translateSummary(diary_id);

                temporaryDiaryService.setSummary(diary_id, summary, engSummary);

                String imageUrl = version.equals("V1") ?
                        stablediffusionService.getTextToImageV1(diary_id) :
                        stablediffusionService.getTextToImageV2(diary_id);

                Map<String, Object> response = new HashMap<>();
                response.put("imageUrl", imageUrl);

                return new ResponseEntity<>(response, HttpStatus.OK);
            } catch (Exception e) {
                attempts++;
                if (attempts >= maxAttempts) {
                    log.error("Failed to get the picture after {} attempts. Error: {}", attempts, e.getMessage());
                    return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
                }
                log.warn("Failed to get the picture on attempt {}. Retrying...", attempts);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    log.error("Thread interrupted while retrying. Error: {}", ex.getMessage());
                    return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            }
        }

        return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
    }

'Project' 카테고리의 다른 글

[졸업프로젝트] Lombok의 @ToString StackOverflowError 해결  (0) 2023.06.05