Skip to content

Commit

Permalink
feat: 예외처리 기능-1 #78
Browse files Browse the repository at this point in the history
  • Loading branch information
yhpark95 committed Nov 7, 2023
1 parent 2e50259 commit 9914a66
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package codesquad.gaemimarble.exception;

import lombok.Getter;

@Getter
public class CustomException extends RuntimeException {
private final String playerId;
private final Long gameId;

public CustomException(String message, String playerId, Long gameId) {
super(message);
this.playerId = playerId;
this.gameId = gameId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package codesquad.gaemimarble.exception;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import codesquad.gaemimarble.game.controller.SocketDataSender;

@RestControllerAdvice
public class GlobalExceptionHandler {

private final SocketDataSender socketDataSender;

public GlobalExceptionHandler(SocketDataSender socketDataSender) {
this.socketDataSender = socketDataSender;
}

@ExceptionHandler(CustomException.class)
public void handleCustomException(CustomException ex) {
socketDataSender.sendErrorMessage(ex.getGameId(), ex.getPlayerId(), ex.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import codesquad.gaemimarble.game.dto.ResponseDTO;
Expand All @@ -23,32 +22,32 @@
@RequiredArgsConstructor
@Slf4j
public class SocketDataSender {
private final ConcurrentMap<Long, Set<WebSocketSession>> gameSocketMap = new ConcurrentHashMap<>();
private final ConcurrentMap<Long, ConcurrentMap<String, WebSocketSession>> gameSocketMap = new ConcurrentHashMap<>();
private final ObjectMapper objectMapper;

public void createRoom(Long gameRoomId) {
gameSocketMap.put(gameRoomId, new HashSet<>());
gameSocketMap.put(gameRoomId, new ConcurrentHashMap<>());
}

public boolean saveSocket(Long gameId, String playerId, WebSocketSession session) {
Set<WebSocketSession> sessions = gameSocketMap.computeIfAbsent(gameId, key -> ConcurrentHashMap.newKeySet());
ConcurrentMap<String, WebSocketSession> socketMap = gameSocketMap.get(gameId);
try {
if (sessions.size() == 4) {
if (socketMap.values().size() == 4) {
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(
new ResponseDTO<>(TypeConstants.ERROR, new SocketErrorResponse("full", "인원이 가득 찼습니다.")))));
new ResponseDTO<>(TypeConstants.ERROR, new SocketErrorResponse("인원이 가득 찼습니다.")))));
session.close();
return false;
}

boolean isDuplicate = sessions.stream()
.anyMatch(s -> s.getAttributes().get("playerId").equals(playerId));
boolean isDuplicate = socketMap.containsKey(playerId);

if (!isDuplicate) {
session.getAttributes().put("playerId", playerId);
sessions.add(session);
return true;
} else {
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(
new ResponseDTO<>(TypeConstants.ERROR, new SocketErrorResponse("duplicate", "이미 접속한 플레이어입니다.")))));
new ResponseDTO<>(TypeConstants.ERROR, new SocketErrorResponse("이미 접속한 플레이어입니다.")))));
return false;
}
} catch (IOException e) {
Expand All @@ -58,7 +57,7 @@ public boolean saveSocket(Long gameId, String playerId, WebSocketSession session
}

public <T> void send(Long gameId, T object) {
for (WebSocketSession session : gameSocketMap.get(gameId)) {
for (WebSocketSession session : gameSocketMap.get(gameId).values()) {
try {
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(object)));
} catch (IOException e) {
Expand All @@ -67,4 +66,13 @@ public <T> void send(Long gameId, T object) {
}
System.out.println("전송 완료");
}

public void sendErrorMessage(Long gameId, String playerId, String message) {
try {
gameSocketMap.get(gameId).get(playerId).sendMessage(new TextMessage(objectMapper.writeValueAsString(
new ResponseDTO<>(TypeConstants.ERROR, new SocketErrorResponse(message)))));
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@

@Getter
public class SocketErrorResponse {
private String errorType; // 나중에 에러 코드로 변경
private String message;

@Builder
public SocketErrorResponse(String errorType, String message) {
this.errorType = errorType;
public SocketErrorResponse(String message) {
this.message = message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.springframework.stereotype.Service;

import codesquad.gaemimarble.exception.CustomException;
import codesquad.gaemimarble.game.dto.GameMapper;
import codesquad.gaemimarble.game.dto.request.GameEndTurnRequest;
import codesquad.gaemimarble.game.dto.request.GameEventResultRequest;
Expand Down Expand Up @@ -249,10 +250,12 @@ public GameUserBoardResponse buyStock(GameStockBuyRequest gameStockBuyRequest) {
.stream()
.filter(s -> s.getName().equals(gameStockBuyRequest.getStockName()))
.findFirst()
.orElseThrow(() -> new RuntimeException("존재하지 않는 주식이름입니다"));
.orElseThrow(() -> new CustomException("존재하지 않는 주식이름입니다", gameStockBuyRequest.getPlayerId(),
gameStockBuyRequest.getGameId()));
if (stock.getRemainingStock() < gameStockBuyRequest.getQuantity()
| player.getCashAsset() < stock.getCurrentPrice() * gameStockBuyRequest.getQuantity()) {
throw new RuntimeException("구매할 수량이 부족하거나, 플레이어 보유 캐쉬가 부족합니다");
throw new CustomException("구매할 수량이 부족하거나, 플레이어 보유 캐쉬가 부족합니다", gameStockBuyRequest.getPlayerId(),
gameStockBuyRequest.getGameId());
}
player.buy(stock, gameStockBuyRequest.getQuantity());
stock.decrementQuantity(gameStockBuyRequest.getQuantity());
Expand Down

0 comments on commit 9914a66

Please sign in to comment.