기존 코드
- 각 api에 대한 Service의 메소드는 try-catch 블록으로 묶어 예외 처리
[문제점]
- 매번 try ~ catch로 묶어야 했기 때문에 코드가 복잡해지고, 예외 처리 로직을 수정할 때마다 모든 Service 메소드를 업데이트해야 하는 단점이 있었습니다.
[해결 방안]
- Spring AOP(Aspect-Oriented Programming)를 활용해서 예외 처리 로직을 하나의 Component에서 관리
중복 코드 AOP로 하나로 묶기
- 중복으로 사용 되는 코드 줄은 43 줄 입니다.
@Slf4j
@Component
@Aspect
public class ExceptionHandlingAspect {
@AfterThrowing(pointcut = "execution(* com.freeder.buclserver.app.*.service.*.*(..))", throwing = "ex")
public void handleServiceException(JoinPoint joinPoint, Exception ex) {
String className = joinPoint.getSignature().getDeclaringType().getName();
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
if (ex instanceof BaseException) {
log.warn(
LogTemplate.getErrorLogTemplate(LogTypeConst.WARN, BaseException.class.getName(),
((BaseException)ex).getErrorMessage(),
((BaseException)ex).getSystemErrorMessage(),
className, methodName, args,
((BaseException)ex).getErrorCode())
);
throw (BaseException)ex;
} else if (ex instanceof IllegalArgumentException) {
log.error(
LogTemplate.getErrorLogTemplate(IllegalArgumentException.class.getName(),
IllegalArgumentException.class.toString(), ex.getMessage(), className,
methodName, args,
HttpStatus.BAD_REQUEST.value()));
throw new BadRequestErrorException("메소드 인수 값이 잘못됐습니다.");
} else if (ex instanceof NullPointerException) {
log.error(
LogTemplate.getErrorLogTemplate(NullPointerException.class.getName(),
NullPointerException.class.toString(), ex.getMessage(), className,
methodName, args,
HttpStatus.BAD_REQUEST.value()));
throw new BadRequestErrorException("Null Point Access 에러 발생");
} else if (ex instanceof DataAccessException) {
log.error(
LogTemplate.getErrorLogTemplate(DataAccessException.class.getName(),
DataAccessException.class.toString(), ex.getMessage(), className,
methodName, args,
HttpStatus.INTERNAL_SERVER_ERROR.value()));
throw new InternalServerErrorException("데이터 액세스 오류", ex);
} else {
log.error(
LogTemplate.getErrorLogTemplate(Exception.class.getName(), DataAccessException.class.toString(),
ex.getMessage(), className, methodName, args,
HttpStatus.INTERNAL_SERVER_ERROR.value()));
throw new InternalServerErrorException("서버 Exception 에러", ex);
}
}
}
결과: 기존 코드 줄 대비 22.2% 감소 & 의존성 문제 해결
전체 코드 줄 검사
- API 기능과 관련 있는 app 폴더의 코드 줄만 검사했습니다.
git ls-files src/main/java/com/freeder/buclserver/app | xargs wc -l
...
167 src/main/java/com/freeder/buclserver/app/trackers/service/TrackersService.java
57 src/main/java/com/freeder/buclserver/app/wishes/WishesController.java
42 src/main/java/com/freeder/buclserver/app/wishes/dto/WishDto.java
156 src/main/java/com/freeder/buclserver/app/wishes/service/WishesService.java
10,234 total
코드 감소율 계산