최종프로젝트가 시작한지 약2주가 지나고 우리팀은 설계를 하고 개발을 시작한지 약 1주일 넘게 지났다
나는 처음 1차 스코프 맡은 스페이드쪽 CRUD를 맡았다. 내가 맡은건 비교적 다른팀원이 했던거보다 엄청 쉬워서
금방 끝낼 수 있었다. 다른팀원분들이 맡은건 웹소켓을 이용한 음성, 채팅 , 프론트 등 다 어려운거를 맡으셔서
나는 쉬운걸 빨리 끝냈으니, 스코프에서 나온 기능들을 빠르게 api를 뚫으려고 한다.
일단 저번 블로그에서 한 CRUD는 됐긴했는데 , 예외처리부분이 안돼 있었다. 예외처리 부분을 공통으로 구현하고
다른사람이 기능을 개발할때 파일을 @@ErrorCode , @@SuccessCode 등 이렇게 파일을 만든 후 간단하게
예외를 찍게 하려고 한다. 아래 코드는 공통 예외처리 부분이다.
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(CustomException.class)
protected ResponseEntity<Mono<CommonReason>> handleCustomException(ServerWebExchange exchange, CustomException e) {
return ResponseEntity.status(e.getBaseCode().getCommonReason().getStatus())
.body(Mono.just(e.getBaseCode().getCommonReason()));
}
}
public interface BaseCode {
public String getRemark();
public CommonReason getCommonReason();
}
@Getter
public class CommonReason {
private final HttpStatus status;
private final int code;
private final String msg;
@Builder
public CommonReason(HttpStatus status, int code, String msg) {
this.status = status;
this.code = code;
this.msg = msg;
}
}
@Getter
@Slf4j
public class CustomException extends RuntimeException {
private final BaseCode baseCode;
public CustomException(BaseCode baseCode) {
super(baseCode.getRemark());
this.baseCode = baseCode;
log.info("ExceptionMethod: {}", getExceptionMethod());
log.info("ErrorCode: {}, ErrorMsg: {}", baseCode.getCommonReason().getCode(), baseCode.getCommonReason().getMsg());
}
public String getExceptionMethod() {
String className = Thread.currentThread().getStackTrace()[3].getClassName();
String methodName = Thread.currentThread().getStackTrace()[3].getMethodName();
return className + "." + methodName;
}
}
@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> originMap = super.getErrorAttributes(request, options);
Map<String, Object> map = new HashMap<>();
map.put("status", ErrorCode.FAIL.getStatus().value());
Throwable throwable = getError(request);
if (throwable instanceof CustomException) {
CustomException ex = (CustomException) getError(request);
map.put("message", ex.getBaseCode().getCommonReason().getMsg());
map.put("status", ex.getBaseCode().getCommonReason().getStatus().value());
}
if (throwable instanceof SecurityException) {
map.put("message", ErrorCode.UNAUTHORIZED.getMsg());
map.put("status", ErrorCode.UNAUTHORIZED.getStatus().value());
}
map.put("path", originMap.get("path"));
map.put("timestamp", originMap.get("timestamp"));
return map;
}
}
이렇게 공통 예외처리 코드를 만들어놓는다.
예외가 발생할때 custom exception 발생 해서 > global exception handler > CommonReason 객체 생성 > 반환
.flatMap(existingMember -> Mono.error(new CustomException(SpaceErrorCode.SPACE_ALREADY_JOINED)))
이렇게 처리를 한다 . 아래는 스페이스에러코드 모음이고 저렇게 계속 맡은 기능 사용자가 따로 파일을 만들어서
저렇게 생성을하고 던져주면 된다 . 매우 간편하다
@Getter
@AllArgsConstructor
public enum SpaceErrorCode implements BaseCode {
SPACE_ENTRY_FAILURE(HttpStatus.BAD_REQUEST, 5000, "입장 실패: 코드가 유효하지 않습니다.", "유효하지 않은 입장 코드입니다."),
SPACE_ALREADY_JOINED(HttpStatus.BAD_REQUEST, 409, "입장 실패: 이미 입장한 사용자입니다.", "이미 입장한 사용자입니다."),
SPACE_NOT_FOUND(HttpStatus.NOT_FOUND, 404, "스페이스 데이터를 찾을 수 없습니다.", "스페이스 데이터가 존재하지 않습니다."),
INVALID_SPACE_NAME(HttpStatus.BAD_REQUEST, 5001, "스페이스 이름은 20자 미만이어야 합니다.", "스페이스 이름이 유효하지 않습니다."),
INVALID_IS_PUBLIC(HttpStatus.BAD_REQUEST, 5002, "공개 여부는 Y 또는 N이어야 합니다.", "공개 여부 값이 유효하지 않습니다."),
;
private final HttpStatus status;
private final int code;
private final String msg;
private final String remark;
@Override
public CommonReason getCommonReason() {
return CommonReason.builder()
.status(status)
.code(code)
.msg(msg)
.build();
}
}
'TIL' 카테고리의 다른 글
TIL - 2024/07/29 (0) | 2024.08.05 |
---|---|
TIL - 2024/07/28 (0) | 2024.08.02 |
TIL - 2024/07/26 (0) | 2024.07.27 |
TIL - 2024/07/19 (0) | 2024.07.19 |
TIL - 2024/07/12 (0) | 2024.07.12 |