응답에 원하는 메세지 추가

김재현·2023년 12월 2일
0

TIL

목록 보기
47/88
post-thumbnail

오늘은 전에 만들었던 할 일 카드 프로젝트의 예외처리 등을 손봤다.

응답에 원하는 메세지 추가

아래는 내가 만든 signup 컨트롤러이다. @Valid로 입력값 걸러서 받는데, 무엇에서 오류가 생긴건지 응답을 주지 않기 때문에 클라이언트는 확실히 알 수 없다.

@PostMapping("/signup")
public ResponseEntity<CommonResponseDto> signup(@Valid @RequestBody SignupRequestDto requestDto, BindingResult bindingResult) {
    List<FieldError> fieldErrors = bindingResult.getFieldErrors();
    if(fieldErrors.size() > 0) {
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage());
            }
        return ResponseEntity.badRequest().body(new CommonResponseDto("허용된 입력값이 아닙니다.",HttpStatus.BAD_REQUEST.value()));
    }
}

FieldErrorDto 생성

그래서 잘못 입력된 필드와 내용을 응답으로 보내기 위해 아래와 같이 Dto를 만들고 List로 묶어줬다.

List<FieldErrorDto> fieldErrorDtoList = fieldErrors.stream().map(FieldErrorDto::new).toList();
public class FieldErrorDto {
    private String field;
    private String message;


    public FieldErrorDto(FieldError fieldError) {
        this.field=fieldError.getField();
        this.message=fieldError.getDefaultMessage();
    }
}

return이 아닌 throw

근데 생각해보니 return이 ResponseEntity<CommonResponseDto>형식으로 되어있어서 어떻게 해야될지 고민했는데, return형식에 구애받지 않는 error로 처리해봐야겠다는 생각을 하게 되었다.
여기서 내가 만든 DtoList를 보낼 수 있는 새로운 exception을 만들어서 거기에 파라미터와 메세지를 전달하면 될 것이라고 생각했다.

Contoller throw

일단 내가 원하는 모양새로 오류가 생기는 경우에 대해 FieldErrorException 이라고 throw를 던져봤다.

throw new FieldErrorException(
	"허용된 username 또는 password 값이 아닙니다.", 
    HttpStatus.BAD_REQUEST.value(), 
    fieldErrorDtoList
    );

exception 커스터마이징

그 후에 위의 throw를 처리 할 수 있게 FieldErrorException을 만들어주었다.

@Getter
public class FieldErrorException extends RuntimeException{
    private final Integer statusCode;
    private final List<FieldErrorDto> fieldErrorDtoList;
    public FieldErrorException(String message, Integer statusCode, List<FieldErrorDto> fieldErrorDtoList) {
        super(message);
        this.statusCode=statusCode;
        this.fieldErrorDtoList=fieldErrorDtoList;
    }
}

ExceptionHandler

ExceptionHandler에서 FieldErrorException를 잡아주었다.
이 때 List<FieldErrorDto> 를 바로 전달하기보단 필드 에러만 중첩된 구조로 보내고 싶었다.
그래서 FieldErrorResponseDto를 새로 만들어서 응답에 넣어줬다.

    @ExceptionHandler({FieldErrorException.class})
    public ResponseEntity<FieldErrorResponseDto> FieldErrorException(FieldErrorException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
                new FieldErrorResponseDto(
                        ex.getMessage(),
                        ex.getStatusCode(),
                        ex.getFieldErrorDtoList()
                ));
    }

FieldErrorResponseDto

@Getter
public class FieldErrorResponseDto {
    private String msg;
    private Integer statusCode;
    private List<FieldErrorDto> fieldError;


    public FieldErrorResponseDto(String msg, int statusCode, List<FieldErrorDto> fieldErrorDtoList) {
        this.msg=msg;
        this.statusCode=statusCode;
        this.fieldError=fieldErrorDtoList;
    }
}

결과는 성공!

원하던 결과를 포스트맨을 통해 확인 할 수 있었다.

profile
I live in Seoul, Korea, Handsome

0개의 댓글