add: common/exception 로직 추가
This commit is contained in:
parent
72a9758866
commit
0de0eca32e
@ -0,0 +1,82 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 관련 예외
|
||||||
|
* HTTP 상태 코드와 함께 사용되는 예외
|
||||||
|
*/
|
||||||
|
public class ApiException extends BusinessException {
|
||||||
|
|
||||||
|
private final HttpStatus httpStatus;
|
||||||
|
|
||||||
|
public ApiException(HttpStatus httpStatus, String message) {
|
||||||
|
super(httpStatus.name(), message);
|
||||||
|
this.httpStatus = httpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiException(HttpStatus httpStatus, String message, Throwable cause) {
|
||||||
|
super(httpStatus.name(), message, cause);
|
||||||
|
this.httpStatus = httpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpStatus getHttpStatus() {
|
||||||
|
return httpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bad Request (400)
|
||||||
|
*/
|
||||||
|
public static ApiException badRequest(String message) {
|
||||||
|
return new ApiException(HttpStatus.BAD_REQUEST, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unauthorized (401)
|
||||||
|
*/
|
||||||
|
public static ApiException unauthorized(String message) {
|
||||||
|
return new ApiException(HttpStatus.UNAUTHORIZED, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forbidden (403)
|
||||||
|
*/
|
||||||
|
public static ApiException forbidden(String message) {
|
||||||
|
return new ApiException(HttpStatus.FORBIDDEN, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not Found (404)
|
||||||
|
*/
|
||||||
|
public static ApiException notFound(String message) {
|
||||||
|
return new ApiException(HttpStatus.NOT_FOUND, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method Not Allowed (405)
|
||||||
|
*/
|
||||||
|
public static ApiException methodNotAllowed(String message) {
|
||||||
|
return new ApiException(HttpStatus.METHOD_NOT_ALLOWED, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conflict (409)
|
||||||
|
*/
|
||||||
|
public static ApiException conflict(String message) {
|
||||||
|
return new ApiException(HttpStatus.CONFLICT, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal Server Error (500)
|
||||||
|
*/
|
||||||
|
public static ApiException internalServerError(String message) {
|
||||||
|
return new ApiException(HttpStatus.INTERNAL_SERVER_ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service Unavailable (503)
|
||||||
|
*/
|
||||||
|
public static ApiException serviceUnavailable(String message) {
|
||||||
|
return new ApiException(HttpStatus.SERVICE_UNAVAILABLE, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class AuthenticationException extends BusinessException {
|
||||||
|
|
||||||
|
public AuthenticationException(String message) {
|
||||||
|
super("AUTHENTICATION_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationException(String message, Throwable cause) {
|
||||||
|
super("AUTHENTICATION_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationException loginFailed() {
|
||||||
|
return new AuthenticationException("아이디 또는 비밀번호가 일치하지 않습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationException tokenExpired() {
|
||||||
|
return new AuthenticationException("토큰이 만료되었습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationException invalidToken() {
|
||||||
|
return new AuthenticationException("유효하지 않은 토큰입니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationException authenticationRequired() {
|
||||||
|
return new AuthenticationException("로그인이 필요합니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class AuthorizationException extends BusinessException {
|
||||||
|
|
||||||
|
public AuthorizationException(String message) {
|
||||||
|
super("AUTHORIZATION_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthorizationException(String message, Object... args) {
|
||||||
|
super("AUTHORIZATION_ERROR", message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthorizationException(String message, Throwable cause) {
|
||||||
|
super("AUTHORIZATION_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthorizationException accessDenied() {
|
||||||
|
return new AuthorizationException("접근 권한이 없습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthorizationException accessDenied(String resource) {
|
||||||
|
return new AuthorizationException(resource + "에 대한 접근 권한이 없습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthorizationException insufficientRole(String requiredRole) {
|
||||||
|
return new AuthorizationException(requiredRole + " 권한이 필요합니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthorizationException ownershipRequired() {
|
||||||
|
return new AuthorizationException("본인만 접근할 수 있습니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
// common/src/main/java/com/ktds/hi/common/exception/BusinessException.java
|
||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 비즈니스 로직 예외의 기본 클래스
|
||||||
|
* 모든 커스텀 예외의 부모 클래스
|
||||||
|
*/
|
||||||
|
public class BusinessException extends RuntimeException {
|
||||||
|
|
||||||
|
private String errorCode;
|
||||||
|
private Object[] args;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지만으로 예외 생성
|
||||||
|
*/
|
||||||
|
public BusinessException(String message) {
|
||||||
|
super(message);
|
||||||
|
this.errorCode = "BUSINESS_ERROR";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지와 원인으로 예외 생성
|
||||||
|
*/
|
||||||
|
public BusinessException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.errorCode = "BUSINESS_ERROR";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 에러 코드와 메시지로 예외 생성
|
||||||
|
*/
|
||||||
|
public BusinessException(String errorCode, String message) {
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 에러 코드, 메시지, 파라미터로 예외 생성
|
||||||
|
*/
|
||||||
|
public BusinessException(String errorCode, String message, Object... args) {
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 에러 코드, 메시지, 원인으로 예외 생성
|
||||||
|
*/
|
||||||
|
public BusinessException(String errorCode, String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 에러 코드 반환
|
||||||
|
*/
|
||||||
|
public String getErrorCode() {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 파라미터 반환
|
||||||
|
*/
|
||||||
|
public Object[] getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 정적 팩토리 메서드 - 일반적인 비즈니스 예외
|
||||||
|
*/
|
||||||
|
public static BusinessException of(String message) {
|
||||||
|
return new BusinessException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 정적 팩토리 메서드 - 에러 코드와 메시지
|
||||||
|
*/
|
||||||
|
public static BusinessException of(String errorCode, String message) {
|
||||||
|
return new BusinessException(errorCode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 정적 팩토리 메서드 - 원인 포함
|
||||||
|
*/
|
||||||
|
public static BusinessException of(String message, Throwable cause) {
|
||||||
|
return new BusinessException(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class BusinessRuleException extends BusinessException {
|
||||||
|
|
||||||
|
public BusinessRuleException(String message) {
|
||||||
|
super("BUSINESS_RULE_VIOLATION", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessRuleException(String message, Object... args) {
|
||||||
|
super("BUSINESS_RULE_VIOLATION", message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessRuleException(String message, Throwable cause) {
|
||||||
|
super("BUSINESS_RULE_VIOLATION", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BusinessRuleException invalidStateTransition(String from, String to) {
|
||||||
|
return new BusinessRuleException(String.format("%s 상태에서 %s 상태로 변경할 수 없습니다", from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BusinessRuleException unauthorizedOperation(String operation) {
|
||||||
|
return new BusinessRuleException(operation + " 작업을 수행할 권한이 없습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BusinessRuleException timeConstraintViolation(String operation) {
|
||||||
|
return new BusinessRuleException(operation + "의 시간 제한을 위반했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BusinessRuleException duplicateOperation(String operation) {
|
||||||
|
return new BusinessRuleException("이미 " + operation + "을(를) 수행했습니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 동시성 관련 예외
|
||||||
|
* 동시 접근, 락 충돌 등에서 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class ConcurrencyException extends BusinessException {
|
||||||
|
|
||||||
|
public ConcurrencyException(String message) {
|
||||||
|
super("CONCURRENCY_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrencyException(String message, Throwable cause) {
|
||||||
|
super("CONCURRENCY_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 낙관적 락 충돌
|
||||||
|
*/
|
||||||
|
public static ConcurrencyException optimisticLockConflict() {
|
||||||
|
return new ConcurrencyException("동시 수정으로 인한 충돌이 발생했습니다. 다시 시도해주세요");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 비관적 락 타임아웃
|
||||||
|
*/
|
||||||
|
public static ConcurrencyException lockTimeout() {
|
||||||
|
return new ConcurrencyException("리소스 잠금 시간이 초과되었습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데드락 발생
|
||||||
|
*/
|
||||||
|
public static ConcurrencyException deadlockDetected() {
|
||||||
|
return new ConcurrencyException("데드락이 감지되었습니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 설정 관련 예외
|
||||||
|
* 애플리케이션 설정 오류, 환경 변수 누락 등에서 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class ConfigurationException extends BusinessException {
|
||||||
|
|
||||||
|
public ConfigurationException(String message) {
|
||||||
|
super("CONFIGURATION_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationException(String message, Throwable cause) {
|
||||||
|
super("CONFIGURATION_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 필수 설정 누락
|
||||||
|
*/
|
||||||
|
public static ConfigurationException missingProperty(String propertyName) {
|
||||||
|
return new ConfigurationException("필수 설정이 누락되었습니다: " + propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 잘못된 설정 값
|
||||||
|
*/
|
||||||
|
public static ConfigurationException invalidValue(String propertyName, String value) {
|
||||||
|
return new ConfigurationException(String.format("잘못된 설정 값입니다. %s: %s", propertyName, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 설정 파일 로드 실패
|
||||||
|
*/
|
||||||
|
public static ConfigurationException loadFailed(String configFile) {
|
||||||
|
return new ConfigurationException("설정 파일 로드에 실패했습니다: " + configFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터 접근 관련 예외
|
||||||
|
* 데이터베이스, 캐시 등 데이터 저장소 접근 시 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class DataAccessException extends BusinessException {
|
||||||
|
|
||||||
|
public DataAccessException(String message) {
|
||||||
|
super("DATA_ACCESS_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataAccessException(String message, Throwable cause) {
|
||||||
|
super("DATA_ACCESS_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터베이스 연결 실패
|
||||||
|
*/
|
||||||
|
public static DataAccessException connectionFailed() {
|
||||||
|
return new DataAccessException("데이터베이스 연결에 실패했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터 정합성 오류
|
||||||
|
*/
|
||||||
|
public static DataAccessException integrityViolation(String detail) {
|
||||||
|
return new DataAccessException("데이터 정합성 오류: " + detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 캐시 접근 실패
|
||||||
|
*/
|
||||||
|
public static DataAccessException cacheAccessFailed() {
|
||||||
|
return new DataAccessException("캐시 접근에 실패했습니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class DataIntegrityException extends BusinessException {
|
||||||
|
|
||||||
|
public DataIntegrityException(String message) {
|
||||||
|
super("DATA_INTEGRITY_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataIntegrityException(String message, Throwable cause) {
|
||||||
|
super("DATA_INTEGRITY_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataIntegrityException foreignKeyViolation(String entity, Object id) {
|
||||||
|
return new DataIntegrityException(String.format("%s(ID: %s)에 참조된 데이터가 있어 삭제할 수 없습니다", entity, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataIntegrityException uniqueConstraintViolation(String field, Object value) {
|
||||||
|
return new DataIntegrityException(String.format("중복된 값입니다. %s: %s", field, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataIntegrityException notNullViolation(String field) {
|
||||||
|
return new DataIntegrityException(field + "은(는) 필수 값입니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class DuplicateResourceException extends BusinessException {
|
||||||
|
|
||||||
|
public DuplicateResourceException(String resourceType, String field, Object value) {
|
||||||
|
super("DUPLICATE_RESOURCE", String.format("이미 존재하는 %s입니다. %s: %s", resourceType, field, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DuplicateResourceException(String message) {
|
||||||
|
super("DUPLICATE_RESOURCE", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DuplicateResourceException(String message, Throwable cause) {
|
||||||
|
super("DUPLICATE_RESOURCE", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DuplicateResourceException username(String username) {
|
||||||
|
return new DuplicateResourceException("사용자", "사용자명", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DuplicateResourceException email(String email) {
|
||||||
|
return new DuplicateResourceException("사용자", "이메일", email);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DuplicateResourceException nickname(String nickname) {
|
||||||
|
return new DuplicateResourceException("사용자", "닉네임", nickname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DuplicateResourceException phone(String phone) {
|
||||||
|
return new DuplicateResourceException("사용자", "전화번호", phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DuplicateResourceException storeName(String storeName) {
|
||||||
|
return new DuplicateResourceException("매장", "매장명", storeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class ExternalServiceException extends BusinessException {
|
||||||
|
|
||||||
|
private final String serviceName;
|
||||||
|
|
||||||
|
public ExternalServiceException(String serviceName, String message) {
|
||||||
|
super("EXTERNAL_SERVICE_ERROR", String.format("%s 서비스 오류: %s", serviceName, message));
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExternalServiceException(String serviceName, String message, Throwable cause) {
|
||||||
|
super("EXTERNAL_SERVICE_ERROR", String.format("%s 서비스 오류: %s", serviceName, message), cause);
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServiceName() {
|
||||||
|
return serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExternalServiceException apiCallFailed(String serviceName, String endpoint) {
|
||||||
|
return new ExternalServiceException(serviceName, endpoint + " API 호출에 실패했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExternalServiceException serviceUnavailable(String serviceName) {
|
||||||
|
return new ExternalServiceException(serviceName, "서비스를 사용할 수 없습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExternalServiceException timeout(String serviceName) {
|
||||||
|
return new ExternalServiceException(serviceName, "응답 시간이 초과되었습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExternalServiceException authenticationFailed(String serviceName) {
|
||||||
|
return new ExternalServiceException(serviceName, "인증에 실패했습니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 처리 관련 예외
|
||||||
|
* 파일 업로드, 다운로드, 변환 등에서 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class FileProcessingException extends BusinessException {
|
||||||
|
|
||||||
|
public FileProcessingException(String message) {
|
||||||
|
super("FILE_PROCESSING_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileProcessingException(String message, Throwable cause) {
|
||||||
|
super("FILE_PROCESSING_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 지원하지 않는 파일 형식
|
||||||
|
*/
|
||||||
|
public static FileProcessingException unsupportedFileType(String fileType) {
|
||||||
|
return new FileProcessingException("지원하지 않는 파일 형식입니다: " + fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 크기 초과
|
||||||
|
*/
|
||||||
|
public static FileProcessingException fileSizeExceeded(long maxSize) {
|
||||||
|
return new FileProcessingException("파일 크기가 제한을 초과했습니다. 최대 크기: " + maxSize + "bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 업로드 실패
|
||||||
|
*/
|
||||||
|
public static FileProcessingException uploadFailed() {
|
||||||
|
return new FileProcessingException("파일 업로드에 실패했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 변환 실패
|
||||||
|
*/
|
||||||
|
public static FileProcessingException conversionFailed(String fromType, String toType) {
|
||||||
|
return new FileProcessingException(String.format("파일 변환에 실패했습니다: %s -> %s", fromType, toType));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JWT 처리 관련 예외
|
||||||
|
* JWT 파싱, 서명 검증 등에서 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class JwtException extends TokenException {
|
||||||
|
|
||||||
|
public JwtException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwtException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JWT 서명 검증 실패
|
||||||
|
*/
|
||||||
|
public static JwtException signatureVerificationFailed() {
|
||||||
|
return new JwtException("JWT 서명 검증에 실패했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JWT 파싱 실패
|
||||||
|
*/
|
||||||
|
public static JwtException parsingFailed() {
|
||||||
|
return new JwtException("JWT 파싱에 실패했습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JWT 클레임 누락
|
||||||
|
*/
|
||||||
|
public static JwtException missingClaim(String claimName) {
|
||||||
|
return new JwtException("필수 클레임이 누락되었습니다: " + claimName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 요청 제한 관련 예외
|
||||||
|
* API 호출 제한, 처리량 제한 등에서 발생하는 예외
|
||||||
|
*/
|
||||||
|
public class RateLimitException extends BusinessException {
|
||||||
|
|
||||||
|
private final long retryAfter; // 재시도 가능 시간 (초)
|
||||||
|
|
||||||
|
public RateLimitException(String message, long retryAfter) {
|
||||||
|
super("RATE_LIMIT_EXCEEDED", message);
|
||||||
|
this.retryAfter = retryAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitException(String message) {
|
||||||
|
this(message, 60); // 기본값: 60초 후 재시도
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRetryAfter() {
|
||||||
|
return retryAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 호출 제한 초과
|
||||||
|
*/
|
||||||
|
public static RateLimitException apiCallLimitExceeded(long retryAfter) {
|
||||||
|
return new RateLimitException("API 호출 제한을 초과했습니다. 잠시 후 다시 시도해주세요", retryAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 동시 요청 제한 초과
|
||||||
|
*/
|
||||||
|
public static RateLimitException concurrentRequestLimitExceeded() {
|
||||||
|
return new RateLimitException("동시 요청 제한을 초과했습니다", 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class ResourceNotFoundException extends BusinessException {
|
||||||
|
|
||||||
|
public ResourceNotFoundException(String resourceType, Object id) {
|
||||||
|
super("RESOURCE_NOT_FOUND", String.format("%s를 찾을 수 없습니다. ID: %s", resourceType, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(String message) {
|
||||||
|
super("RESOURCE_NOT_FOUND", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(String resourceType, String field, Object value) {
|
||||||
|
super("RESOURCE_NOT_FOUND", String.format("%s를 찾을 수 없습니다. %s: %s", resourceType, field, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(String message, Throwable cause) {
|
||||||
|
super("RESOURCE_NOT_FOUND", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceNotFoundException byId(String resourceType, Object id) {
|
||||||
|
return new ResourceNotFoundException(resourceType, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceNotFoundException user(Long userId) {
|
||||||
|
return new ResourceNotFoundException("사용자", userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceNotFoundException store(Long storeId) {
|
||||||
|
return new ResourceNotFoundException("매장", storeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceNotFoundException review(Long reviewId) {
|
||||||
|
return new ResourceNotFoundException("리뷰", reviewId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceNotFoundException userByUsername(String username) {
|
||||||
|
return new ResourceNotFoundException("사용자", "사용자명", username);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 보안 관련 예외
|
||||||
|
* 인증, 인가 외의 보안 관련 예외
|
||||||
|
*/
|
||||||
|
public class SecurityException extends BusinessException {
|
||||||
|
|
||||||
|
public SecurityException(String message) {
|
||||||
|
super("SECURITY_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecurityException(String message, Throwable cause) {
|
||||||
|
super("SECURITY_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 보안 정책 위반
|
||||||
|
*/
|
||||||
|
public static SecurityException policyViolation(String policy) {
|
||||||
|
return new SecurityException("보안 정책 위반: " + policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 의심스러운 활동 감지
|
||||||
|
*/
|
||||||
|
public static SecurityException suspiciousActivity(String activity) {
|
||||||
|
return new SecurityException("의심스러운 활동이 감지되었습니다: " + activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP 차단
|
||||||
|
*/
|
||||||
|
public static SecurityException ipBlocked(String ip) {
|
||||||
|
return new SecurityException("차단된 IP 주소입니다: " + ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 서비스 레이어 예외
|
||||||
|
* 비즈니스 로직 실행 중 발생하는 일반적인 예외
|
||||||
|
*/
|
||||||
|
public class ServiceException extends BusinessException {
|
||||||
|
|
||||||
|
public ServiceException(String message) {
|
||||||
|
super("SERVICE_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String message, Throwable cause) {
|
||||||
|
super("SERVICE_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String errorCode, String message) {
|
||||||
|
super(errorCode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 서비스 일시 중단
|
||||||
|
*/
|
||||||
|
public static ServiceException temporarilyUnavailable(String serviceName) {
|
||||||
|
return new ServiceException("서비스가 일시적으로 이용할 수 없습니다: " + serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 처리 한도 초과
|
||||||
|
*/
|
||||||
|
public static ServiceException limitExceeded(String limitType) {
|
||||||
|
return new ServiceException("처리 한도를 초과했습니다: " + limitType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JWT 토큰 관련 예외
|
||||||
|
* 토큰 만료, 유효하지 않은 토큰 등에 사용
|
||||||
|
*/
|
||||||
|
public class TokenException extends BusinessException {
|
||||||
|
|
||||||
|
public TokenException(String message) {
|
||||||
|
super("TOKEN_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TokenException(String message, Throwable cause) {
|
||||||
|
super("TOKEN_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 토큰 만료 예외
|
||||||
|
*/
|
||||||
|
public static TokenException expired() {
|
||||||
|
return new TokenException("토큰이 만료되었습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 토큰 형식 오류 예외
|
||||||
|
*/
|
||||||
|
public static TokenException invalid() {
|
||||||
|
return new TokenException("유효하지 않은 토큰입니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 토큰 누락 예외
|
||||||
|
*/
|
||||||
|
public static TokenException missing() {
|
||||||
|
return new TokenException("토큰이 필요합니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 잘못된 토큰 타입 예외
|
||||||
|
*/
|
||||||
|
public static TokenException wrongType(String expectedType) {
|
||||||
|
return new TokenException(expectedType + " 토큰이 필요합니다");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.ktds.hi.common.exception;
|
||||||
|
|
||||||
|
public class ValidationException extends BusinessException {
|
||||||
|
|
||||||
|
public ValidationException(String message) {
|
||||||
|
super("VALIDATION_ERROR", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationException(String message, Object... args) {
|
||||||
|
super("VALIDATION_ERROR", message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationException(String field, String message) {
|
||||||
|
super("VALIDATION_ERROR", String.format("%s: %s", field, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationException(String message, Throwable cause) {
|
||||||
|
super("VALIDATION_ERROR", message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationException requiredField(String fieldName) {
|
||||||
|
return new ValidationException(fieldName + "은(는) 필수 입력 항목입니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationException invalidFormat(String fieldName) {
|
||||||
|
return new ValidationException(fieldName + "의 형식이 올바르지 않습니다");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationException outOfRange(String fieldName, Object min, Object max) {
|
||||||
|
return new ValidationException(String.format("%s는 %s와 %s 사이의 값이어야 합니다", fieldName, min, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationException lengthExceeded(String fieldName, int maxLength) {
|
||||||
|
return new ValidationException(String.format("%s는 %d자 이하로 입력해주세요", fieldName, maxLength));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user