티스토리 뷰
체스미션에서 View(Client)에 원하는 에러 메시지를 전송하기위해 아래와 같이 try-catch문을 남발하여 에러가 발생하는 경우 에러 메시지를 DTO에 담아 보내도록 구현했었다.
알고보니 Spark Java에서는 예외를 처리해주는 exception 메서드를 지원하고 있었고, 이를 사용하는 방향으로 리팩토링을 진행했다.
Controller
에러가 발생하면 ErrorResponseDto에 에러 메시지를 담아 보내도록 구현하였다. 현재 모든 에러를 잡도록(일명 포켓몬 캐치..) 구현하였는데 이는 추후 수정이 필요해보인다.
exception(Exception.class, (e, req, res) -> {
res.body(GSON.toJson(new ErrorResponseDto(e.getMessage())));
});
이렇게 exception 메서드를 사용하면서 중복된 try-catch문 사용을 피할 수 있었다.
private ChessResponseDto load() {
final ChessGame chessGame = chessService.load();
return chessService.createChessResponseDto(chessGame);
}
private ChessResponseDto start() {
ChessGame chessGame = chessService.load();
chessGame = chessService.start(chessGame);
return chessService.createChessResponseDto(chessGame);
}
DTO
ErrorResponseDto
에러 출력만을 위한 DTO를 만들었다. 이를 만듬으로써 ChessResponseDto, StatusResponseDto에서 불필요한 코드를 제거할 수 있었다.
public class ErrorResponseDto {
private final String status;
private final String message;
public ErrorResponseDto(final String message) {
this.status = "error";
this.message = message;
}
}
StatusResponseDto
Before
기존에 status 명령어의 응답에 사용하기위한 StatusResponseDto 클래스에는 점수, 승패에 관한 데이터 뿐만아니라 응답 성공 여부를 나타내는 code, 에러 메시지를 담는 message가 추가적으로 필요했으며, 이 하나의 클래스로 성공, 실패를 모두 커버하기 위해 불필요한 값("", 0 등)을 넣어야했었다. (생성자도 여러개..)
public class StatusResponseDto {
private final String code;
private final String message;
private final String myTurn;
private final String opponentTurn;
private final double myScore;
private final double opponentScore;
private final String result;
public StatusResponseDto(final ChessGame chessGame, final double myScore, final double opponentScore,
final String result) {
this("success", "", chessGame, myScore, opponentScore, result);
}
public StatusResponseDto(final String code, final String message, final ChessGame chessGame) {
this(code, message, chessGame, 0, 0, "");
}
public StatusResponseDto(final String code, final String message, final ChessGame chessGame, final double myScore,
final double opponentScore,
final String result) {
this.code = code;
this.message = message;
this.myTurn = chessGame.getTurn().getName();
this.opponentTurn = chessGame.getTurn().getOpposite().getName();
this.myScore = myScore;
this.opponentScore = opponentScore;
this.result = result;
}
}
After
성공했을 때만 사용하는 DTO로 변화되었기때문에 생성자가 하나만 있어도 된다!!
public class StatusResponseDto {
private final String status;
private final String myTurn;
private final String opponentTurn;
private final double myScore;
private final double opponentScore;
private final String result;
public StatusResponseDto(final ChessGame chessGame, final double myScore, final double opponentScore,
final String result) {
this.status = "success";
this.myTurn = chessGame.getTurn().getName();
this.opponentTurn = chessGame.getTurn().getOpposite().getName();
this.myScore = myScore;
this.opponentScore = opponentScore;
this.result = result;
}
}
ChessResponseDto
위와 비슷하므로 생략!!
결과
변경 후에도 에러메시지가 잘 출력되는 모습을 확인했다.
To-Be
1. 현재 내 맘대로 status에 성공이면 "success", 실패하면 "error"를 담아서 보내므로, HTTP 상태 코드를 이용한 방법으로 변경하면 좋을 것 같다. 400(Bad Request)상태를 반환하도록 시도는 해봤는데, JS에서 이를 어떻게 처리해야할 지 모르겠어서 일단 스탑한 상태!! 그리고 이렇게 되면 어떠한 HTTP 상태코드를 보내야할지 잘 모르겠다..ㅎ(HTTP 상태 코드)
2. 현재 exception 메서드에서 모든 에러를 잡도록(일명 포켓몬 캐치..) 구현하였는데 이는 추후 내가 지정한 에러만을 잡도록 수정해야겠다. 커스텀 에러 클래스를 하나 만들어보는 것도 좋을 것 같다.
Ref.
https://sparkjava.com/documentation
https://self-learning-java-tutorial.blogspot.com/2015/01/spark-java-exception-mapping.html
'Backend > Java' 카테고리의 다른 글
[모락] byte[]를 String으로 변환하기 (2) | 2022.08.26 |
---|---|
DAO, DTO, Service, Controller (feat. 체스미션) (0) | 2022.04.06 |
처음 만난 SparkJava (0) | 2022.04.03 |
공유 중인 가변 데이터는 동기화해 사용하라 (0) | 2022.03.30 |
Enum에서 상수를 사용하는 방법 (4) | 2022.03.17 |