Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/main/java/com/carecode/core/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public enum ErrorCode {
BOOKING_NOT_FOUND("F002", "예약을 찾을 수 없습니다", HttpStatus.NOT_FOUND),
BOOKING_ALREADY_EXISTS("F003", "이미 예약된 시간입니다", HttpStatus.CONFLICT),
BOOKING_ACCESS_DENIED("F004", "예약에 대한 권한이 없습니다", HttpStatus.FORBIDDEN),
/** 요청 자체는 멀쩡한데 예약의 현재 상태가 맞지 않다(이미 취소됨, 이미 완료됨). 409. */
BOOKING_STATE_CONFLICT("F005", "예약 상태가 맞지 않아 처리할 수 없습니다", HttpStatus.CONFLICT),

// ===== 정책 관련 에러 (P000) =====
POLICY_NOT_FOUND("P001", "정책을 찾을 수 없습니다", HttpStatus.NOT_FOUND),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.carecode.core.annotation.RateLimit;
import com.carecode.core.web.BaseController;
import com.carecode.domain.user.app.CurrentUserFacade;
import com.carecode.core.exception.CareCodeException;
import com.carecode.core.exception.CareServiceException;
import com.carecode.domain.chatbot.dto.request.ChatbotMessageRequest;
import com.carecode.domain.chatbot.dto.response.ChatbotMessageResponse;
Expand Down Expand Up @@ -56,6 +57,10 @@ public ResponseEntity<ChatbotMessageResponse> sendMessage(
} catch (CareServiceException e) {
log.error("챗봇 처리 오류: {}", e.getMessage());
throw e;
} catch (CareCodeException e) {
// 누구의 잘못인지 이미 정해진 예외다. 감싸면 전부 500 이 된다.
// (CareServiceException 은 바로 위에서 이미 다시 던진다.)
throw e;
} catch (Exception e) {
log.error("챗봇 처리 중 예상치 못한 오류: {}", e.getMessage(), e);
throw new CareServiceException("챗봇 처리 중 오류가 발생했습니다: " + e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.carecode.domain.chatbot.service;

import com.carecode.core.annotation.LogExecutionTime;
import com.carecode.core.exception.CareCodeException;
import com.carecode.core.exception.CareServiceException;
import com.carecode.core.exception.ResourceNotFoundException;
import com.carecode.domain.chatbot.dto.request.ChatbotMessageRequest;
Expand Down Expand Up @@ -140,6 +141,9 @@ public ChatbotMessageResponse processMessage(ChatbotMessageRequest request) {
.timestamp(LocalDateTime.now())
.build();

} catch (CareCodeException | CareServiceException e) {
// 누구의 잘못인지 이미 정해진 예외다. 감싸면 전부 500 이 된다.
throw e;
} catch (Exception e) {
log.error("챗봇 메시지 처리 중 오류 발생: {}", e.getMessage(), e);
// 상세한 오류 정보 로깅
Expand Down Expand Up @@ -171,6 +175,8 @@ public List<ChatbotChatHistoryDtoResponse> getChatHistory(String userId, String
.map(this::convertToHistoryResponse)
.toList();

} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("대화 기록 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("대화 기록 조회 중 오류가 발생했습니다.", e);
Expand All @@ -192,6 +198,8 @@ public List<ChatbotSessionDtoResponse> getSessions(String userId, int page, int
.map(this::convertToSessionResponse)
.toList();

} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("세션 목록 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("세션 목록 조회 중 오류가 발생했습니다.", e);
Expand All @@ -211,6 +219,8 @@ public void processFeedback(Long messageId, boolean isHelpful) {
message.setIsHelpful(isHelpful);
chatMessageRepository.save(message);

} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("메시지 피드백 처리 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("메시지 피드백 처리 중 오류가 발생했습니다.", e);
Expand All @@ -230,6 +240,8 @@ public List<ChatbotChatHistoryDtoResponse> getMessagesByIntentType(String userId
return messages.stream()
.map(this::convertToHistoryResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("의도 타입별 메시지 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("의도 타입별 메시지 조회 중 오류가 발생했습니다.", e);
Expand All @@ -249,6 +261,8 @@ public List<ChatbotChatHistoryDtoResponse> getMessagesByDateRange(String userId,
return messages.stream()
.map(this::convertToHistoryResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("기간별 메시지 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("기간별 메시지 조회 중 오류가 발생했습니다.", e);
Expand All @@ -268,6 +282,8 @@ public List<ChatbotChatHistoryDtoResponse> getMessagesByHelpfulStatus(String use
return messages.stream()
.map(this::convertToHistoryResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("도움됨 여부별 메시지 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("도움됨 여부별 메시지 조회 중 오류가 발생했습니다.", e);
Expand All @@ -287,6 +303,8 @@ public List<ChatbotChatHistoryDtoResponse> searchMessagesByKeyword(String userId
return messages.stream()
.map(this::convertToHistoryResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("키워드로 메시지 검색 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("키워드로 메시지 검색 중 오류가 발생했습니다.", e);
Expand All @@ -306,6 +324,8 @@ public List<ChatbotSessionDtoResponse> getSessionsByStatus(String userId, ChatSe
return sessions.stream()
.map(this::convertToSessionResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("상태별 세션 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("상태별 세션 조회 중 오류가 발생했습니다.", e);
Expand All @@ -325,6 +345,8 @@ public List<ChatbotSessionDtoResponse> getSessionsByDateRange(String userId, Loc
return sessions.stream()
.map(this::convertToSessionResponse)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("기간별 세션 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("기간별 세션 조회 중 오류가 발생했습니다.", e);
Expand All @@ -340,6 +362,8 @@ public long getSessionCountByUser(String userId) {
User user = resolveUser(userId);

return chatSessionRepository.countByUser(user);
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("사용자별 세션 수 조회 중 오류 발생: {}", e.getMessage(), e);
throw new CareServiceException("사용자별 세션 수 조회 중 오류가 발생했습니다.", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.carecode.domain.community.service;

import com.carecode.core.exception.BusinessException;
import com.carecode.core.exception.ErrorCode;
import com.carecode.core.exception.CareServiceException;
import com.carecode.core.exception.CommentAccessDeniedException;
import com.carecode.core.exception.PostAccessDeniedException;
Expand Down Expand Up @@ -366,7 +368,7 @@ private User getCurrentUser() {
// 이메일 형식 검증
if (userEmail == null || !userEmail.contains("@")) {
log.error("getCurrentUser() - 유효하지 않은 이메일 형식: {}", userEmail);
throw new CareServiceException("유효하지 않은 사용자 정보입니다.");
throw new BusinessException(ErrorCode.UNAUTHORIZED, "유효하지 않은 사용자 정보입니다.");
}

return userRepository.findByEmailAndDeletedAtIsNull(userEmail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.carecode.core.annotation.LogExecutionTime;
import com.carecode.core.exception.BusinessException;
import com.carecode.core.exception.CareServiceException;
import com.carecode.core.exception.ErrorCode;
import com.carecode.core.exception.ResourceNotFoundException;
import com.carecode.domain.facility.dto.response.BookingResponse;
Expand Down Expand Up @@ -155,11 +154,11 @@ public void cancelBooking(Long bookingId, String userId) {

if (booking.getStatus() == CareFacilityBooking.BookingStatus.CANCELLED
|| booking.getStatus() == CareFacilityBooking.BookingStatus.REJECTED) {
throw new CareServiceException("이미 취소되었거나 반려된 예약입니다.");
throw new BusinessException(ErrorCode.BOOKING_STATE_CONFLICT, "이미 취소되었거나 반려된 예약입니다.");
}

if (booking.getStatus() == CareFacilityBooking.BookingStatus.COMPLETED) {
throw new CareServiceException("이미 완료된 예약은 취소할 수 없습니다.");
throw new BusinessException(ErrorCode.BOOKING_STATE_CONFLICT, "이미 완료된 예약은 취소할 수 없습니다.");
}

booking.cancel("사용자에 의해 취소됨");
Expand All @@ -178,11 +177,11 @@ public BookingResponse updateBooking(Long bookingId, UpdateBookingRequest reques

if (booking.getStatus() == CareFacilityBooking.BookingStatus.CANCELLED
|| booking.getStatus() == CareFacilityBooking.BookingStatus.REJECTED) {
throw new CareServiceException("취소되었거나 반려된 예약은 수정할 수 없습니다.");
throw new BusinessException(ErrorCode.BOOKING_STATE_CONFLICT, "취소되었거나 반려된 예약은 수정할 수 없습니다.");
}

if (booking.getStatus() == CareFacilityBooking.BookingStatus.COMPLETED) {
throw new CareServiceException("완료된 예약은 수정할 수 없습니다.");
throw new BusinessException(ErrorCode.BOOKING_STATE_CONFLICT, "완료된 예약은 수정할 수 없습니다.");
}

// 예약 시간이 바뀌면 다시 검증한다. 종료 시각만 바뀌어도 겹침 여부가 달라지므로 둘 다 비교한다.
Expand Down Expand Up @@ -235,13 +234,13 @@ private void validateBookingTime(CareFacility facility,
LocalDateTime endTime,
Long excludeBookingId) {
if (startTime == null || endTime == null) {
throw new CareServiceException("예약 시작/종료 시간은 필수입니다.");
throw new BusinessException(ErrorCode.INVALID_INPUT, "예약 시작/종료 시간은 필수입니다.");
}
if (!endTime.isAfter(startTime)) {
throw new CareServiceException("예약 종료 시간은 시작 시간보다 뒤여야 합니다.");
throw new BusinessException(ErrorCode.INVALID_INPUT, "예약 종료 시간은 시작 시간보다 뒤여야 합니다.");
}
if (startTime.isBefore(LocalDateTime.now())) {
throw new CareServiceException("과거 시간으로는 예약할 수 없습니다.");
throw new BusinessException(ErrorCode.INVALID_INPUT, "과거 시간으로는 예약할 수 없습니다.");
}

long overlapping = bookingRepository.countOverlappingBookings(
Expand All @@ -252,7 +251,8 @@ private void validateBookingTime(CareFacility facility,
: DEFAULT_CONCURRENT_BOOKING_LIMIT;

if (overlapping >= capacity) {
throw new CareServiceException("해당 시간에 예약 가능한 자리가 없습니다. 다른 시간을 선택해주세요.");
throw new BusinessException(ErrorCode.BOOKING_ALREADY_EXISTS,
"해당 시간에 예약 가능한 자리가 없습니다. 다른 시간을 선택해주세요.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public HealthRecordResponse createHealthRecord(HealthCreateHealthRecordRequest r
return healthRecordMapper.toResponse(savedRecord);
} catch (NumberFormatException e) {
log.error("잘못된 아동 ID 형식: {}", request.getChildId());
throw new CareServiceException("잘못된 아동 ID 형식입니다: " + request.getChildId(), e);
throw new BusinessException(ErrorCode.INVALID_CHILD_ID,
"잘못된 아동 ID 형식입니다: " + request.getChildId());
} catch (CareCodeException e) {
throw e;
} catch (CareServiceException e) {
Expand Down Expand Up @@ -216,6 +217,9 @@ public List<HealthRecordResponse> getHealthRecordsByDateRangeAsc(Long childId, L
// 우리가 던진 예외는 자기 상태 코드를 들고 있다. 아래 catch 에 걸리면 404·403 이
// 전부 500 으로 덮이고, 남의 자녀 접근 거부가 서버 오류로 보고된다.
throw e;
} catch (CareServiceException e) {
// CareCodeException 은 바로 위에서 이미 다시 던진다. 이쪽 체계도 같이 통과시킨다.
throw e;
} catch (Exception e) {
log.error("기간별 건강 기록 조회 실패: {}", e.getMessage(), e);
throw new CareServiceException("기간별 건강 기록 조회 중 오류가 발생했습니다.", e);
Expand All @@ -240,6 +244,8 @@ public List<HealthRecordResponse> getHealthRecordsByType(Long childId, HealthRec
// 우리가 던진 예외는 자기 상태 코드를 들고 있다. 아래 catch 에 걸리면 404·403 이
// 전부 500 으로 덮이고, 남의 자녀 접근 거부가 서버 오류로 보고된다.
throw e;
} catch (CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("타입별 건강 기록 조회 실패: {}", e.getMessage(), e);
throw new CareServiceException("타입별 건강 기록 조회 중 오류가 발생했습니다.", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.carecode.domain.notification.service;

import com.carecode.core.annotation.LogExecutionTime;
import com.carecode.core.exception.CareCodeException;
import com.carecode.core.exception.CareServiceException;
import com.carecode.core.exception.ResourceNotFoundException;
import com.carecode.domain.notification.dto.request.NotificationRegisterPushTokenRequest;
Expand Down Expand Up @@ -49,6 +50,9 @@ public List<NotificationSettingsResponse> getUserPreferences(String userId) {
return preferences.stream()
.map(this::convertToDto)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
// 누구의 잘못인지 이미 정해진 예외다. 감싸면 전부 500 이 된다.
throw e;
} catch (Exception e) {
log.error("사용자별 알림 설정 조회 실패: {}", e.getMessage(), e);
throw new CareServiceException("알림 설정 조회 중 오류가 발생했습니다.", e);
Expand All @@ -68,6 +72,8 @@ public NotificationSettingsResponse getPreferenceByType(String userId, Notificat

return preference.map(this::convertToDto)
.orElseGet(() -> convertToDto(createDefaultPreference(user, notificationType)));
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("알림 타입별 설정 조회 실패: {}", e.getMessage(), e);
throw new CareServiceException("알림 설정 조회 중 오류가 발생했습니다.", e);
Expand All @@ -93,6 +99,8 @@ public NotificationSettingsResponse savePreference(String userId, NotificationSe

NotificationPreference savedPreference = preferenceRepository.save(preference);
return convertToDto(savedPreference);
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("알림 설정 저장 실패: {}", e.getMessage(), e);
throw new CareServiceException("알림 설정 저장 중 오류가 발생했습니다.", e);
Expand All @@ -118,6 +126,8 @@ public NotificationSettingsResponse updateChannelPreference(String userId, Strin

NotificationPreference savedPreference = preferenceRepository.save(preference);
return convertToDto(savedPreference);
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("채널별 설정 업데이트 실패: {}", e.getMessage(), e);
throw new CareServiceException("채널별 설정 업데이트 중 오류가 발생했습니다.", e);
Expand Down Expand Up @@ -154,6 +164,8 @@ public void disableAllNotifications(String userId) {
preference.setInAppEnabled(false);
preferenceRepository.save(preference);
}
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("모든 알림 설정 비활성화 실패: {}", e.getMessage(), e);
throw new CareServiceException("알림 설정 비활성화 중 오류가 발생했습니다.", e);
Expand All @@ -178,6 +190,8 @@ public void resetToDefault(String userId) {
for (Notification.NotificationType type : Notification.NotificationType.values()) {
createDefaultPreference(user, type);
}
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("알림 설정 초기화 실패: {}", e.getMessage(), e);
throw new CareServiceException("알림 설정 초기화 중 오류가 발생했습니다.", e);
Expand All @@ -195,6 +209,8 @@ public List<NotificationSettingsResponse> getEnabledPreferencesByType(Notificati
return preferences.stream()
.map(this::convertToDto)
.collect(Collectors.toList());
} catch (CareCodeException | CareServiceException e) {
throw e;
} catch (Exception e) {
log.error("알림 타입별 활성화된 설정 조회 실패: {}", e.getMessage(), e);
throw new CareServiceException("활성화된 설정 조회 중 오류가 발생했습니다.", e);
Expand Down
Loading
Loading