Skip to content

Commit

Permalink
투표 기능 예외 처리 (#49)
Browse files Browse the repository at this point in the history
* feat: 투표 생성 시 존재하지 않는 데이터를 요구한 경우 예외 처리

* feat: 중복 투표를 진행하는 경우 예외 처리

* feat: 투표가 이미 종료된 게시글에 투표하려는 경우 예외 처리

* style: 로직 순서 변경

* feat: 존재하지 않는 데이터 요청 시 예외 처리

* feat: 카테고리가 'CASUAL'인 게시글에서 투표를 수정하려는 경우 예외 처리

* feat: 해당 게시글에서 투표한 기록이 없을 때 투표를 수정하려는 경우 예외 처리
  • Loading branch information
Hanjaemo authored Feb 14, 2024
1 parent 5098b8e commit b832ffa
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package balancetalk.global.exception;

import lombok.Getter;

@Getter
public class BalanceTalkException extends RuntimeException {

private final ErrorCode errorCode;

public BalanceTalkException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
28 changes: 28 additions & 0 deletions src/main/java/balancetalk/global/exception/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package balancetalk.global.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

import static org.springframework.http.HttpStatus.*;

@Getter
@RequiredArgsConstructor
public enum ErrorCode {
// 400
MISMATCHED_BALANCE_OPTION(BAD_REQUEST, "선택한 선택지는 다른 게시글에 속해 있습니다."),
EXPIRED_POST_DEADLINE(BAD_REQUEST, "투표가 이미 종료된 게시글입니다."),
UNMODIFIABLE_VOTE(BAD_REQUEST, "투표 수정이 불가능한 게시글입니다."),

// 404
NOT_FOUND_POST(NOT_FOUND, "존재하지 않는 게시글입니다."),
NOT_FOUND_BALANCE_OPTION(NOT_FOUND, "존재하지 않는 선택지입니다."),
NOT_FOUND_MEMBER(NOT_FOUND, "존재하지 않는 회원입니다."),
NOT_FOUND_VOTE(NOT_FOUND, "해당 게시글에서 투표한 기록이 존재하지 않습니다."),

// 409
ALREADY_VOTE(CONFLICT, "투표는 한 번만 가능합니다.");

private final HttpStatus httpStatus;
private final String message;
}
18 changes: 18 additions & 0 deletions src/main/java/balancetalk/global/exception/ErrorResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package balancetalk.global.exception;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ErrorResponse {

private HttpStatus httpStatus;
private String message;

public static ErrorResponse from(ErrorCode errorCode) {
return new ErrorResponse(errorCode.getHttpStatus(), errorCode.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package balancetalk.global.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(BalanceTalkException.class)
public ResponseEntity<ErrorResponse> handleBalanceTalkException(BalanceTalkException e) {
ErrorResponse errorResponse = ErrorResponse.from(e.getErrorCode());
log.error("exception message = {}", e.getMessage());
return ResponseEntity.status(errorResponse.getHttpStatus()).body(errorResponse);
}
}
5 changes: 5 additions & 0 deletions src/main/java/balancetalk/module/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ public class Member extends BaseTimeEntity {

@OneToMany(mappedBy = "reporter")
private List<Report> reports = new ArrayList<>(); // 신고한 기록

public boolean hasVoted(Post post) {
return votes.stream()
.anyMatch(vote -> vote.getBalanceOption().getPost().equals(post));
}
}
4 changes: 4 additions & 0 deletions src/main/java/balancetalk/module/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ public void init() {
public boolean notContainsBalanceOption(BalanceOption option) {
return !options.contains(option);
}

public boolean hasDeadlineExpired() {
return deadline.isBefore(LocalDateTime.now());
}
}
34 changes: 22 additions & 12 deletions src/main/java/balancetalk/module/vote/application/VoteService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package balancetalk.module.vote.application;

import static balancetalk.global.exception.ErrorCode.*;

import balancetalk.global.exception.BalanceTalkException;
import balancetalk.module.member.domain.Member;
import balancetalk.module.member.domain.MemberRepository;
import balancetalk.module.post.domain.BalanceOption;
Expand Down Expand Up @@ -28,22 +31,29 @@ public class VoteService {

public Vote createVote(Long postId, VoteRequest voteRequest) {
Post post = postRepository.findById(postId)
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_POST));
BalanceOption balanceOption = balanceOptionRepository.findById(voteRequest.getSelectedOptionId())
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_BALANCE_OPTION));
Member member = memberRepository.findById(voteRequest.getMemberId())
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_MEMBER));

if (post.notContainsBalanceOption(balanceOption)) {
throw new RuntimeException();
throw new BalanceTalkException(MISMATCHED_BALANCE_OPTION);
}
if (member.hasVoted(post)) {
throw new BalanceTalkException(ALREADY_VOTE);
}
if (post.hasDeadlineExpired()) {
throw new BalanceTalkException(EXPIRED_POST_DEADLINE);
}

Member member = memberRepository.findById(voteRequest.getMemberId())
.orElseThrow();
return voteRepository.save(voteRequest.toEntity(balanceOption, member));
}

@Transactional(readOnly = true)
public List<VotingStatusResponse> readVotingStatus(Long postId) {
Post post = postRepository.findById(postId)
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_POST));

List<BalanceOption> options = post.getOptions();
List<VotingStatusResponse> responses = new ArrayList<>();
Expand All @@ -61,20 +71,20 @@ public List<VotingStatusResponse> readVotingStatus(Long postId) {

public Vote updateVote(Long postId, VoteRequest voteRequest) {
Post post = postRepository.findById(postId)
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_POST));

if (post.isCasual()) {
throw new IllegalArgumentException(); // TODO 예외 처리
throw new BalanceTalkException(UNMODIFIABLE_VOTE);
}

Member member = memberRepository.findById(voteRequest.getMemberId())
.orElseThrow();
BalanceOption newSelectedOption = balanceOptionRepository.findById(voteRequest.getSelectedOptionId())
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_BALANCE_OPTION));
Member member = memberRepository.findById(voteRequest.getMemberId())
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_MEMBER));
Vote findVote = member.getVotes().stream()
.filter(vote -> vote.getBalanceOption().getPost().equals(post))
.findFirst()
.orElseThrow();
.orElseThrow(() -> new BalanceTalkException(NOT_FOUND_VOTE));
return findVote.changeBalanceOption(newSelectedOption);
}
}

0 comments on commit b832ffa

Please sign in to comment.