• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

전역 에러 처리 메시지 관리

23.10.23 18:06 작성 조회수 226

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

강의에 보면 enum에 TEST라고 하시고 에러메시지를 정적으로 입력하셨는데 , 메시지properties로 따로 관리하는 방법은 없을까요?
TEST(HttpStatus.INTERNAL_SERVER_ERROR,"001",messageSource.getMessage("001")),

001 = "business Exception test"

 

돌아가는 코드는 아니지만 이런식으로 답변 주시면 감사하겠습니다

답변 2

·

답변을 작성해보세요.

0

안녕하세요. messages.properties 파일에 다음과 같이 어떤 type에 따라서 어떤 오류메세지를 반환할지를 정해줄 수 있구요

NotNull={0}은(는) 필수 입력 값 입니다.
NotBlank={0}은(는) 빈값 일 수 없습니다.
typeMismatch={0}에 잘못된 타입을 입력하셨습니다. {1} 형으로 입력해주세요.
Size={0}은 {2}부터 {1}사이의 숫자를 입력해야합니다.

 

GlobalExceptionHandler에 messageSource 빈을 주입 후 messages.properties에 있는 값을 읽어와서 구성할 수 있습니다. 타입오류인 경우도 아래처럼 처리가 가능합니다.

@Slf4j
@RequiredArgsConstructor
@RestControllerAdvice
public class GlobalExceptionHandler {

    private final MessageSource messageSource;

    /**
     * javax.bean validation 처리
     */
    @ExceptionHandler(value = {
            MethodArgumentNotValidException.class
    })
    public ResponseEntity<ErrorResponse> handleBadRequest(MethodArgumentNotValidException e, HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        e.getBindingResult().getAllErrors()
                .forEach(c -> {
                    String field = ((FieldError) c).getField();
                    String errorMessage = getErrorMessage(c);
                    sb.append(errorMessage).append(" ");
                });
        String message = sb.toString();
        ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST.toString(), message);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(errorResponse);
    }

    /**
     * 필드 TypeMismatch 오류 처리
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<ErrorResponse> handleTypeMismatchExceptions(HttpMessageNotReadableException ex, HttpServletRequest request){

        Pattern errorFieldPattern = Pattern.compile("\\[[\"](.*?)[\"]\\]");
        Matcher errorFieldMatcher = errorFieldPattern.matcher(ex.getCause().getMessage());
        String errorField = errorFieldMatcher.find() ? errorFieldMatcher.group(1) : "FAIL";

        Pattern rightTypePattern = Pattern.compile("[`](.*?)[`]");
        Matcher rightTypeMatcher = rightTypePattern.matcher(ex.getMessage());
        String rightType = rightTypeMatcher.find() ? rightTypeMatcher.group(1) : "?";
        String errorMessage = messageSource.getMessage("typeMismatch", new Object[] {errorField, rightType}, Locale.KOREA);
        
        ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST.toString(), errorMessage);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(errorResponse);
    }

    private String getErrorMessage(ObjectError error) {
        String[] codes = error.getCodes();
        for (String code : codes) {
            try {
                String message = messageSource.getMessage(code, error.getArguments(), Locale.KOREA);
                return message;
            } catch (NoSuchMessageException ignored) {}
        }
        return error.getDefaultMessage();
    }
    

}

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.10.25

안녕하세요 vnfthr 님, 인프런 AI 인턴이에요.

강의에서 보신 예시 코드는 enum을 사용하여 특정 에러에 대한 메시지를 정적으로 관리하고 계신 것 같네요. 메시지를 properties 파일로 따로 관리하는 방법은 가능합니다.

먼저, 메시지를 관리할 properties 파일을 생성합니다. 예를 들어, messages.properties 파일을 생성합니다. 그리고 해당 파일에 에러 코드와 에러 메시지를 key-value 형식으로 작성합니다. 예를 들어, “001=business Exception test”와 같이 작성하면 됩니다.

그 후, 메시지를 사용하는 곳에서는 messageSource bean을 사용하여 properties 파일에서 해당 에러 메시지를 가져오는 방식으로 구현하시면 됩니다.

예시 코드를 보여드리면 다음과 같습니다.

@Value("${file.path}")
private String filePath;

@Autowired
private MessageSource messageSource;

...

// 에러 메시지 사용 예시
String errorCode = "001";
String errorMessage = messageSource.getMessage(errorCode, null, LocaleContextHolder.getLocale());

이렇게 하시면 properties 파일에 작성된 에러 메시지를 가져와서 사용하실 수 있습니다.

참고로, messageSource는 Spring Framework에서 제공하는 기능이므로 Spring Framework를 사용하고 계시다면 해당 기능을 활용하실 수 있습니다.

위의 내용이 참고가 되었는지 확인 부탁드립니다. 추가로 궁금한 점이 있다면 언제든지 물어보세요. 감사합니다!