[TIL-CH4] spring-advanced 과제 트러블슈팅

김유란·2025년 2월 26일

CH 4 spring-advanced 과제 트러블슈팅🚨


1️⃣ 배열 크기를 초과한 인덱스 접근으로 인한 오류

💡 배경

AOP를 활용하여 API 로깅을 구현하고 테스트하는 과정에서 BAD_REQUEST가 반환되는 것을 발견하였습니다.

🔍 발단

Object[] args = joinPoint.getArgs();
String requestBody = objectMapper.writeValueAsString(args);

오류의 원인은 위 코드에서 args.length가 1 이하임에도 불구하고 args[1]에 접근하려고 했기 때문에 ArrayIndexOutOfBoundsException이 발생한 것이었습니다.

⚠️ 전개

예외 발생 원인은 이해했지만, 응답이 BAD_REQUEST로 반환되고 "Invalid JWT token, 유효하지 않는 JWT 토큰 입니다." 라는 로그가 작성되는 이유가 궁금해 코드를 확인해 보았습니다. 그 결과, 해당 로그가 JwtFilter 클래스에서 기록되고 있음을 알게되었습니다.

💣 위기

AOP에서 예외가 발생했지만, Spring MVC에서 처리되지 않으면 예외는 Spring DispatcherServlet을 거쳐 최종적으로 Filter까지 전파됩니다. 따라서 처리되지 않은 예외가 JwtFilter 클래스의 doFilter()에서 감지되어 아래 코드에서 BAD_REQUEST 응답이 반환된 것입니다.

catch (Exception e) {
    log.error("Invalid JWT token, 유효하지 않는 JWT 토큰 입니다.", e);
    httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "유효하지 않는 JWT 토큰입니다.");
}

과제 코드의 Spring MVC 요청 처리 흐름은 다음과 같습니다.

  1. Filter 실행
  2. Spring Controller 실행
    • Logging 클래스의 @Around AOP 적용
  3. AOP 실행
    • ArrayIndexOutOfBoundsException 발생
  4. 예외 전파
    • AOP → Controller → Spring MVC → DispatcherServlet → Filter
  5. Filter에서 예외 감지

✅ 절정

Object[] args = joinPoint.getArgs();
String requestBody = "N/A";  // 기본값 설정

if (args.length > 1) {
    requestBody = objectMapper.writeValueAsString(args[1]);
}

위와 같이 requestBody의 기본값을 설정하고, 경우에 따라 args[1]에 접근하도록 수정하여 오류를 해결하였습니다.

📌 결말

배열에 접근할 때는 크기를 초과한 인덱스에 접근하지 않도록 주의해야겠다고 느꼈으며, 예상과 다른 응답이 반환된 덕분에 Spring의 예외 처리 흐름을 이해할 수 있는 좋은 기회가 되었습니다.

0개의 댓글