Skip to content

Commit

Permalink
feat: 전반적인 예외 처리 (#103)
Browse files Browse the repository at this point in the history
* feat: 예외 처리 핸들러 추가

* feat: Offering 예외 처리 코드 추가

* feat: Comment 예외 처리 코드 추가

* feat: Member 예외 처리 코드 추가

* feat: OfferingMember 예외 처리 코드 추가

* feat: Offering 예외 처리 상세 코드 추가

* feat: 에러 코드 적용

* feat: 도메인 검증 로직

* feat: DTO 검증 로직

---------

Co-authored-by: masonkimseoul <masonkimseoul@gmail.com>
  • Loading branch information
2 people authored and ChooSeoyeon committed Oct 11, 2024
1 parent 6b7ab72 commit 7a9d176
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.zzang.chongdae.comment.exception;

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

import com.zzang.chongdae.global.exception.ErrorMessage;
import com.zzang.chongdae.global.exception.ErrorResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum CommentErrorCode implements ErrorResponse {

NOT_FOUND(BAD_REQUEST, "해당 댓글이 존재하지 않습니다.");

private final HttpStatus status;
private final String message;

@Override
public ErrorMessage getErrorMessage() {
return new ErrorMessage(this.message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
Expand All @@ -34,6 +35,7 @@ public class CommentEntity extends BaseTimeEntity {
@ManyToOne
private OfferingEntity offering;

@NotNull
@Column(length = 80)
private String content;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.zzang.chongdae.comment.service;

import com.zzang.chongdae.comment.domain.CommentWithRole;
import com.zzang.chongdae.comment.exception.CommentErrorCode;
import com.zzang.chongdae.comment.repository.CommentRepository;
import com.zzang.chongdae.comment.repository.entity.CommentEntity;
import com.zzang.chongdae.comment.service.dto.CommentAllResponse;
Expand All @@ -10,9 +11,12 @@
import com.zzang.chongdae.comment.service.dto.CommentRoomAllResponseItem;
import com.zzang.chongdae.comment.service.dto.CommentSaveRequest;
import com.zzang.chongdae.comment.service.dto.CommentLatestResponse;
import com.zzang.chongdae.global.exception.MarketException;
import com.zzang.chongdae.member.exception.MemberErrorCode;
import com.zzang.chongdae.member.repository.MemberRepository;
import com.zzang.chongdae.member.repository.entity.MemberEntity;
import com.zzang.chongdae.offering.domain.OfferingWithRole;
import com.zzang.chongdae.offering.exception.OfferingErrorCode;
import com.zzang.chongdae.offering.repository.OfferingRepository;
import com.zzang.chongdae.offering.repository.entity.OfferingEntity;
import com.zzang.chongdae.offeringmember.domain.OfferingMemberRole;
Expand All @@ -30,17 +34,17 @@ public class CommentService {

public void saveComment(CommentSaveRequest request) {
MemberEntity loginMember = memberRepository.findById(request.memberId())
.orElseThrow(); // TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(MemberErrorCode.NOT_FOUND));
OfferingEntity offering = offeringRepository.findById(request.offeringId())
.orElseThrow();// TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(OfferingErrorCode.NOT_FOUND));

CommentEntity comment = new CommentEntity(loginMember, offering, request.content());
commentRepository.save(comment);
}

public CommentRoomAllResponse getAllCommentRoom(Long loginMemberId) {
MemberEntity loginMember = memberRepository.findById(loginMemberId)
.orElseThrow(); // TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(MemberErrorCode.NOT_FOUND));

List<OfferingWithRole> offeringsWithRole = offeringRepository.findAllWithRoleByMember(loginMember);
List<CommentRoomAllResponseItem> responseItems = offeringsWithRole.stream()
Expand All @@ -59,7 +63,7 @@ private CommentRoomAllResponseItem toCommentRoomAllResponseItem(OfferingWithRole
OfferingEntity offering = offeringWithRole.getOffering();
OfferingMemberRole role = offeringWithRole.getRole();
CommentEntity latestComment = commentRepository.findTopByOfferingOrderByCreatedAtDesc(offering)
.orElseThrow(); // TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(CommentErrorCode.NOT_FOUND));
return new CommentRoomAllResponseItem(
offering.getId(),
offering.getTitle(),
Expand All @@ -70,7 +74,7 @@ private CommentRoomAllResponseItem toCommentRoomAllResponseItem(OfferingWithRole
public CommentAllResponse getAllComment(Long offeringId, Long loginMemberId) {
validateMemberExistence(loginMemberId);
OfferingEntity offering = offeringRepository.findById(offeringId)
.orElseThrow(); // TODO: 예외 처리하기
.orElseThrow(() -> new MarketException(OfferingErrorCode.NOT_FOUND));

List<CommentWithRole> commentsWithRole = commentRepository.findAllWithRoleByOffering(offering);
List<CommentAllResponseItem> responseItems = commentsWithRole.stream()
Expand All @@ -81,7 +85,7 @@ public CommentAllResponse getAllComment(Long offeringId, Long loginMemberId) {

private void validateMemberExistence(Long memberId) {
if (!memberRepository.existsById(memberId)) {
throw new IllegalArgumentException("존재하지 않는 사용자가 로그인을 했네요"); // TODO: 예외 처리하기
throw new MarketException(MemberErrorCode.NOT_FOUND);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
package com.zzang.chongdae.comment.service.dto;

public record CommentSaveRequest(Long memberId, Long offeringId, String content) {
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

public record CommentSaveRequest(@NotNull
Long memberId,

@NotNull
Long offeringId,

@NotBlank(message = "댓글 내용을 입력해주세요.")
@Size(max = 80, message = "댓글 내용의 길이를 확인해주세요.")
String content) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.zzang.chongdae.global.exception;

public record ErrorMessage(String value) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.zzang.chongdae.global.exception;

import org.springframework.http.HttpStatus;

public interface ErrorResponse {

HttpStatus getStatus();

ErrorMessage getErrorMessage();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.zzang.chongdae.global.exception;

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

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler
public ResponseEntity<ErrorMessage> handle(MarketException e) {
ErrorResponse errorResponse = e.getErrorResponse();
return ResponseEntity
.status(errorResponse.getStatus())
.body(errorResponse.getErrorMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.zzang.chongdae.global.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class MarketException extends RuntimeException {

private final ErrorResponse errorResponse;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.zzang.chongdae.member.exception;

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

import com.zzang.chongdae.global.exception.ErrorMessage;
import com.zzang.chongdae.global.exception.ErrorResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum MemberErrorCode implements ErrorResponse {

NOT_FOUND(BAD_REQUEST, "해당 사용자가 존재하지 않습니다.");

private final HttpStatus status;
private final String message;

@Override
public ErrorMessage getErrorMessage() {
return new ErrorMessage(this.message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class MemberEntity extends BaseTimeEntity {
private Long id;

@NotNull
@Column(unique = true)
@Column(unique = true, length = 10)
private String nickname;

public boolean isSameMember(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.zzang.chongdae.offering.exception;

import org.springframework.http.HttpStatus;

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

import com.zzang.chongdae.global.exception.ErrorMessage;
import com.zzang.chongdae.global.exception.ErrorResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum OfferingErrorCode implements ErrorResponse {

NOT_FOUND(BAD_REQUEST, "해당 공모가 존재하지 않습니다."),
PARTICIPANT_FULL(BAD_REQUEST, "해당 공모에 참여 가능한 인원수를 초과하였습니다."),
CANNOT_PARTICIPATE(BAD_REQUEST, "참여할 수 없는 공모입니다.");

private final HttpStatus status;
private final String message;

@Override
public ErrorMessage getErrorMessage() {
return new ErrorMessage(this.message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.AccessLevel;
Expand All @@ -37,6 +38,7 @@ public class OfferingEntity extends BaseTimeEntity {
private MemberEntity member;

@NotNull
@Column(length = 30)
private String title;

@NotNull
Expand All @@ -58,15 +60,18 @@ public class OfferingEntity extends BaseTimeEntity {
private String meetingAddressDetail;

@NotNull
@Positive
private Integer totalCount;

@NotNull
@Positive
private Integer currentCount = 1;

@NotNull
private Boolean isManualConfirmed;

@NotNull
@Positive
private BigDecimal totalPrice;

public void updateCurrentCount() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.zzang.chongdae.offering.service;

import com.zzang.chongdae.global.exception.MarketException;
import com.zzang.chongdae.member.exception.MemberErrorCode;
import com.zzang.chongdae.member.repository.MemberRepository;
import com.zzang.chongdae.member.repository.entity.MemberEntity;
import com.zzang.chongdae.offering.domain.OfferingPrice;
import com.zzang.chongdae.offering.domain.OfferingStatus;
import com.zzang.chongdae.offering.exception.OfferingErrorCode;
import com.zzang.chongdae.offering.repository.OfferingRepository;
import com.zzang.chongdae.offering.repository.entity.OfferingEntity;
import com.zzang.chongdae.offering.service.dto.OfferingAllResponse;
Expand All @@ -27,13 +30,13 @@ public class OfferingService {

public OfferingDetailResponse getOfferingDetail(Long offeringId, Long memberId) {
OfferingEntity offering = offeringRepository.findById(offeringId)
.orElseThrow(); // TODO: 예외 처리하기
.orElseThrow(() -> new MarketException(OfferingErrorCode.NOT_FOUND));

OfferingPrice offeringPrice = offering.toOfferingPrice();
OfferingStatus offeringStatus = offering.toOfferingStatus();

MemberEntity member = memberRepository.findById(memberId)
.orElseThrow(); // TODO: 로그인 추가하면 교체 필요
.orElseThrow(() -> new MarketException(MemberErrorCode.NOT_FOUND));
Boolean isParticipated = offeringMemberRepository.existsByOfferingAndMember(offering, member);

return new OfferingDetailResponse(offering, offeringPrice, offeringStatus, isParticipated);
Expand All @@ -54,7 +57,7 @@ public OfferingAllResponse getAllOffering(Long lastId, Integer pageSize) {

public OfferingMeetingResponse getOfferingMeeting(Long offeringId) {
OfferingEntity offering = offeringRepository.findById(offeringId)
.orElseThrow(); // TODO: 예외 처리하기
.orElseThrow(() -> new MarketException(OfferingErrorCode.NOT_FOUND));
return new OfferingMeetingResponse(offering.toOfferingMeeting());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.zzang.chongdae.offeringmember.exception;

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

import com.zzang.chongdae.global.exception.ErrorMessage;
import com.zzang.chongdae.global.exception.ErrorResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum OfferingMemberErrorCode implements ErrorResponse {

DUPLICATED(BAD_REQUEST, "이미 참여한 공모엔 참여할 수 없습니다.");

private final HttpStatus status;
private final String message;

@Override
public ErrorMessage getErrorMessage() {
return new ErrorMessage(this.message);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.zzang.chongdae.offeringmember.service;

import com.zzang.chongdae.global.exception.MarketException;
import com.zzang.chongdae.member.exception.MemberErrorCode;
import com.zzang.chongdae.member.repository.MemberRepository;
import com.zzang.chongdae.member.repository.entity.MemberEntity;
import com.zzang.chongdae.offering.domain.OfferingStatus;
import com.zzang.chongdae.offering.exception.OfferingErrorCode;
import com.zzang.chongdae.offering.repository.OfferingRepository;
import com.zzang.chongdae.offering.repository.entity.OfferingEntity;
import com.zzang.chongdae.offeringmember.domain.OfferingMemberRole;
import com.zzang.chongdae.offeringmember.exception.OfferingMemberErrorCode;
import com.zzang.chongdae.offeringmember.repository.OfferingMemberRepository;
import com.zzang.chongdae.offeringmember.repository.entity.OfferingMemberEntity;
import com.zzang.chongdae.offeringmember.service.dto.ParticipationRequest;
Expand All @@ -24,9 +28,9 @@ public class OfferingMemberService {
@Transactional
public Long participate(ParticipationRequest request) {
MemberEntity member = memberRepository.findById(request.memberId())
.orElseThrow(); // TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(MemberErrorCode.NOT_FOUND));
OfferingEntity offering = offeringRepository.findById(request.offeringId())
.orElseThrow();// TODO: 예외처리 하기
.orElseThrow(() -> new MarketException(OfferingErrorCode.NOT_FOUND));
validateParticipate(offering, member);

OfferingMemberEntity offeringMember = new OfferingMemberEntity(
Expand All @@ -44,13 +48,13 @@ private void validateParticipate(OfferingEntity offering, MemberEntity member) {
private void validateClosed(OfferingEntity offering) {
OfferingStatus offeringStatus = offering.toOfferingStatus();
if (offeringStatus.isClosed()) {
throw new IllegalArgumentException("아이고 못들어가요 ㅜㅜ"); // TODO: 예외처리 하기
throw new MarketException(OfferingErrorCode.CANNOT_PARTICIPATE);
}
}

private void validateDuplicate(OfferingEntity offering, MemberEntity member) {
if (offeringMemberRepository.existsByOfferingAndMember(offering, member)) {
throw new IllegalArgumentException("이미 참여한 공모엔 참여할 수 없습니다."); // TODO: 예외처리 하기
throw new MarketException(OfferingMemberErrorCode.DUPLICATED);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
package com.zzang.chongdae.offeringmember.service.dto;

public record ParticipationRequest(Long memberId, Long offeringId) {
import jakarta.validation.constraints.NotNull;

public record ParticipationRequest(@NotNull
Long memberId,

@NotNull
Long offeringId) {
}

0 comments on commit 7a9d176

Please sign in to comment.