Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9ab8009
refactor(#195/exception): 전역 예외 핸들러 처리 수정
kaswhy Aug 26, 2025
bb6811b
refactor(#195/user): user 관련 예외 처리 수정
kaswhy Aug 26, 2025
cc589be
refactor(#195/auth): auth 관련 예외 처리 수정
kaswhy Aug 26, 2025
c797e8e
refactor(#195/game): game 서비스 내부 중복 코드 삭제
kaswhy Aug 26, 2025
2d480f9
refactor(#195/recruit): recruit 관련 예외 처리 수정
kaswhy Aug 26, 2025
aa35cb3
refactor(#195/resource): resource 관련 예외 처리 수정
kaswhy Aug 26, 2025
3de3ca9
chore(#195/domain): 사용하지 않는 import 문, 메서드 삭제
kaswhy Aug 26, 2025
040649c
refactor(#195/study): study 관련 예외 처리 수정
kaswhy Aug 26, 2025
b5bf6c2
refactor(#200/exception): 전역 예외 핸들러 처리 수정
kaswhy Aug 26, 2025
ff86610
refactor(#200/user): user 관련 예외 처리 수정
kaswhy Aug 26, 2025
8e40d7a
refactor(#200/auth): auth 관련 예외 처리 수정
kaswhy Aug 26, 2025
9f37af4
refactor(#200/game): game 서비스 내부 중복 코드 삭제
kaswhy Aug 26, 2025
7ea4d04
refactor(#200/recruit): recruit 관련 예외 처리 수정
kaswhy Aug 26, 2025
34040a6
refactor(#200/resource): resource 관련 예외 처리 수정
kaswhy Aug 26, 2025
ec3b580
chore(#200/domain): 사용하지 않는 import 문, 메서드 삭제
kaswhy Aug 26, 2025
d7aeac9
refactor(#200/study): study 관련 예외 처리 수정
kaswhy Aug 26, 2025
d8c56bb
Merge remote-tracking branch 'origin/feature/issue-197' into feature/…
kaswhy Aug 26, 2025
45f1536
refactor(#195/domain): 반영되지 않은 예외 처리 반영 및 import 문 수정
kaswhy Aug 26, 2025
a952c84
refactor(#200/domain): 반영되지 않은 예외 처리 반영 및 import 문 수정
kaswhy Aug 26, 2025
7b50f20
Merge remote-tracking branch 'origin/feature/issue-197' into feature/…
kaswhy Aug 26, 2025
f60ecc3
refactor(#200/resources): 404 처리를 위한 yml 파일 설정 추가
kaswhy Aug 26, 2025
4bf3203
refactor(#200/security): api 변경에 맞게 security 설정 변경
kaswhy Aug 26, 2025
39fc019
refactor(#200/study): 권한 체크 및 사용자 존재 여부 검증 로직 순서 변경
kaswhy Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import inha.gdgoc.domain.auth.dto.response.CodeVerificationResponse;
import inha.gdgoc.domain.auth.dto.response.LoginResponse;
import inha.gdgoc.domain.auth.exception.AuthErrorCode;
import inha.gdgoc.domain.auth.exception.AuthException;
import inha.gdgoc.domain.auth.service.AuthCodeService;
import inha.gdgoc.domain.auth.service.AuthService;
import inha.gdgoc.domain.auth.service.MailService;
import inha.gdgoc.domain.auth.service.RefreshTokenService;
import inha.gdgoc.domain.user.entity.User;
import inha.gdgoc.domain.user.repository.UserRepository;
import inha.gdgoc.global.dto.response.ApiResponse;
import inha.gdgoc.global.error.BusinessException;
import jakarta.servlet.http.HttpServletResponse;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
Expand Down Expand Up @@ -62,6 +62,7 @@ public ResponseEntity<ApiResponse<Map<String, Object>, Void>> handleGoogleCallba
HttpServletResponse response
) {
Map<String, Object> data = authService.processOAuthLogin(code, response);

return ResponseEntity.ok(ApiResponse.ok(OAUTH_LOGIN_SIGNUP_SUCCESS, data));
}

Expand All @@ -72,11 +73,9 @@ public ResponseEntity<?> refreshAccessToken(
log.info("리프레시 토큰 요청 받음. 토큰 존재 여부: {}", refreshToken != null);

if (refreshToken == null) {
throw new BusinessException(AuthErrorCode.INVALID_COOKIE);
throw new AuthException(AuthErrorCode.INVALID_COOKIE);
}

log.info("리프레시 토큰 값: {}", refreshToken);

try {
String newAccessToken = refreshTokenService.refreshAccessToken(refreshToken);
AccessTokenResponse accessTokenResponse = new AccessTokenResponse(newAccessToken);
Expand All @@ -85,7 +84,7 @@ public ResponseEntity<?> refreshAccessToken(
ApiResponse.ok(ACCESS_TOKEN_REFRESH_SUCCESS, accessTokenResponse, null));
} catch (Exception e) {
log.error("리프레시 토큰 처리 중 오류: {}", e.getMessage(), e);
throw new BusinessException(AuthErrorCode.INVALID_REFRESH_TOKEN);
throw new AuthException(AuthErrorCode.INVALID_REFRESH_TOKEN);
}
}

Expand All @@ -105,12 +104,12 @@ public ResponseEntity<ApiResponse<Void, Void>> logout() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication == null || !authentication.isAuthenticated()) {
throw new BusinessException(UNAUTHORIZED_USER);
throw new AuthException(UNAUTHORIZED_USER);
}

String email = authentication.getName();
User user = userRepository.findByEmail(email)
.orElseThrow(() -> new BusinessException(USER_NOT_FOUND));
.orElseThrow(() -> new AuthException(USER_NOT_FOUND));
Long userId = user.getId();

log.info("로그아웃 시도: 사용자 ID: {}, 이메일: {}", userId, email);
Expand Down Expand Up @@ -142,7 +141,7 @@ public ResponseEntity<ApiResponse<Void, Void>> responseResponseEntity(

return ResponseEntity.ok(ApiResponse.ok(CODE_CREATION_SUCCESS));
}
throw new BusinessException(USER_NOT_FOUND);
throw new AuthException(USER_NOT_FOUND);
}

@PostMapping("/password-reset/verify")
Expand All @@ -163,7 +162,7 @@ public ResponseEntity<ApiResponse<Void, Void>> resetPassword(
// TODO 서비스 단으로
Optional<User> user = userRepository.findByEmail(passwordResetRequest.email());
if (user.isEmpty()) {
throw new BusinessException(USER_NOT_FOUND);
throw new AuthException(USER_NOT_FOUND);
}

User foundUser = user.get();
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/inha/gdgoc/domain/auth/exception/AuthException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package inha.gdgoc.domain.auth.exception;

import inha.gdgoc.global.error.BusinessException;
import inha.gdgoc.global.error.ErrorCode;

public class AuthException extends BusinessException {

public AuthException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,7 @@ public List<GameUserResponse> saveGameResultAndGetRanking(GameUserRequest gameUs
GameUser gameUser = gameUserRequest.toEntity();
gameUserRepository.save(gameUser);

LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul"));
LocalDateTime startOfDay = today.atStartOfDay(); // 00:00:00
LocalDateTime endOfDay = today.atTime(23, 59, 59); // 23:59:59

// 전체 유저 순위 리스트 가져오기
List<GameUser> results = gameUserRepository.findAllByCreatedAtBetweenOrderByTypingSpeedAsc(startOfDay,
endOfDay);

return results.stream()
.map(user -> new GameUserResponse(results.indexOf(user) + 1, user))
.collect(Collectors.toList());
return findUserRankings();
}

public List<GameUserResponse> findUserRankings() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public ResponseEntity<ApiResponse<SpecifiedMemberResponse, Void>> getSpecifiedMe
@RequestParam Long userId
) {
SpecifiedMemberResponse response = recruitMemberService.findSpecifiedMember(userId);

return ResponseEntity.ok(ApiResponse.ok(MEMBER_RETRIEVED_SUCCESS, response));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package inha.gdgoc.domain.recruit.dto.response;

import inha.gdgoc.global.entity.BaseEntity;
import inha.gdgoc.domain.recruit.entity.RecruitMember;

public class SpecifiedMemberResponse extends BaseEntity {
private String name;
private String major;
private String studentId;
private boolean isPayed;
public record SpecifiedMemberResponse(
String name,
String major,
String studentId,
boolean isPayed
) {

public SpecifiedMemberResponse(String name, String major, String studentId, boolean isPayed) {
this.name = name;
this.major = major;
this.studentId = studentId;
this.isPayed = isPayed;
public static SpecifiedMemberResponse from(RecruitMember member) {
return new SpecifiedMemberResponse(
member.getName(),
member.getMajor(),
member.getStudentId(),
Boolean.TRUE.equals(member.getIsPayed())
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package inha.gdgoc.domain.recruit.exception;

import inha.gdgoc.global.error.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@RequiredArgsConstructor
public enum RecruitMemberErrorCode implements ErrorCode {

// 404 NOT FOUND
RECRUIT_MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 멤버를 찾을 수 없습니다.");

private final HttpStatus status;
private final String message;

@Override
public HttpStatus getStatus() {
return status;
}

@Override
public String getMessage() {
return message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package inha.gdgoc.domain.recruit.exception;

import inha.gdgoc.global.error.BusinessException;
import inha.gdgoc.global.error.ErrorCode;

public class RecruitMemberException extends BusinessException {

public RecruitMemberException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package inha.gdgoc.domain.recruit.service;

import static inha.gdgoc.domain.recruit.exception.RecruitMemberErrorCode.RECRUIT_MEMBER_NOT_FOUND;

import com.fasterxml.jackson.databind.ObjectMapper;
import inha.gdgoc.domain.recruit.dto.request.ApplicationRequest;
import inha.gdgoc.domain.recruit.dto.response.SpecifiedMemberResponse;
import inha.gdgoc.domain.recruit.entity.Answer;
import inha.gdgoc.domain.recruit.entity.RecruitMember;
import inha.gdgoc.domain.recruit.enums.InputType;
import inha.gdgoc.domain.recruit.enums.SurveyType;
import inha.gdgoc.domain.recruit.exception.RecruitMemberException;
import inha.gdgoc.domain.recruit.repository.AnswerRepository;
import inha.gdgoc.domain.recruit.repository.RecruitMemberRepository;
import jakarta.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -52,9 +54,9 @@ public boolean isRegisteredPhoneNumber(String phoneNumber) {
}

public SpecifiedMemberResponse findSpecifiedMember(Long id) {
Optional<RecruitMember> foundMember = recruitMemberRepository.findById(id);
RecruitMember member = foundMember.get();
return new SpecifiedMemberResponse(member.getName(), member.getMajor(), member.getStudentId(),
member.getIsPayed());
RecruitMember member = recruitMemberRepository.findById(id)
.orElseThrow(() -> new RecruitMemberException(RECRUIT_MEMBER_NOT_FOUND));

return SpecifiedMemberResponse.from(member);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import inha.gdgoc.domain.auth.service.AuthService;
import inha.gdgoc.domain.resource.dto.response.S3ResultResponse;
import inha.gdgoc.domain.resource.enums.S3KeyType;
import inha.gdgoc.domain.resource.exception.ResourceErrorCode;
import inha.gdgoc.domain.resource.exception.ResourceException;
import inha.gdgoc.domain.resource.service.S3Service;
import inha.gdgoc.global.dto.response.ApiResponse;
import inha.gdgoc.global.error.BusinessException;
import java.io.IOException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
Expand All @@ -18,8 +19,6 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@RestController
@RequestMapping("/api/v1/resource")
@RequiredArgsConstructor
Expand All @@ -38,7 +37,7 @@ public ResponseEntity<ApiResponse<S3ResultResponse, Void>> uploadImage(
@RequestParam("s3key") S3KeyType s3key
) {
if (file.getSize() > MAX_FILE_SIZE) {
throw new BusinessException(ResourceException.INVALID_BIG_FILE);
throw new ResourceException(ResourceErrorCode.INVALID_BIG_FILE);
}

Long userId = authService.getAuthenticationUserId(authentication);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package inha.gdgoc.domain.resource.exception;

import inha.gdgoc.global.error.ErrorCode;
import org.springframework.http.HttpStatus;

public enum ResourceErrorCode implements ErrorCode {

// 413
INVALID_BIG_FILE(HttpStatus.PAYLOAD_TOO_LARGE, "파일 크기는 10Mb를 넘을 수 없습니다.");

private final HttpStatus status;
private final String message;

ResourceErrorCode(HttpStatus status, String message) {
this.status = status;
this.message = message;
}

@Override
public HttpStatus getStatus() {
return status;
}

@Override
public String getMessage() {
return message;
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
package inha.gdgoc.domain.resource.exception;

import inha.gdgoc.global.error.BusinessException;
import inha.gdgoc.global.error.ErrorCode;
import org.springframework.http.HttpStatus;

public enum ResourceException implements ErrorCode {
public class ResourceException extends BusinessException {

// 413
INVALID_BIG_FILE(HttpStatus.PAYLOAD_TOO_LARGE, "파일 크기는 10Mb를 넘을 수 없습니다.");

private final HttpStatus status;
private final String message;

ResourceException(HttpStatus status, String message) {
this.status = status;
this.message = message;
}

@Override
public HttpStatus getStatus() {
return status;
}

@Override
public String getMessage() {
return message;
public ResourceException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package inha.gdgoc.domain.study.exception;

import inha.gdgoc.global.error.ErrorCode;
import org.springframework.http.HttpStatus;

public enum StudyAttendeeErrorCode implements ErrorCode {

// 400 Bad Request
INVALID_PAGE(HttpStatus.BAD_REQUEST, "page가 1보다 작을 수 없습니다."),

// 404 Not Found
STUDY_ATTENDEE_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 스터디에 지원한 지원자 정보가 없습니다."),

// 409 Conflict
STUDY_ALREADY_APPLIED(HttpStatus.CONFLICT, "이미 가입한 스터디입니다.");

private final HttpStatus status;
private final String message;

StudyAttendeeErrorCode(HttpStatus status, String message) {
this.status = status;
this.message = message;
}

@Override
public HttpStatus getStatus() {
return status;
}

@Override
public String getMessage() {
return message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package inha.gdgoc.domain.study.exception;

import inha.gdgoc.global.error.BusinessException;
import inha.gdgoc.global.error.ErrorCode;

public class StudyAttendeeException extends BusinessException {

public StudyAttendeeException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package inha.gdgoc.domain.study.exception;

import inha.gdgoc.global.error.ErrorCode;
import org.springframework.http.HttpStatus;

public enum StudyErrorCode implements ErrorCode {

// 400 Bad Request
INVALID_PAGE(HttpStatus.BAD_REQUEST, "page가 1보다 작을 수 없습니다."),

// 403 FORBIDDEN
STUDY_APPLICANT_ACCESS_DENIED(HttpStatus.FORBIDDEN, "본인이 만든 스터디의 지원자 정보만 확인할 수 있습니다."),

// 404 NOT FOUND
STUDY_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 스터디입니다.");

private final HttpStatus status;
private final String message;

StudyErrorCode(HttpStatus status, String message) {
this.status = status;
this.message = message;
}

@Override
public HttpStatus getStatus() {
return status;
}

@Override
public String getMessage() {
return message;
}
}
Loading
Loading