#Backend

NPE 하나를 팀의 방어 체계로 바꾸기까지

NPE 하나를 팀의 방어 체계로 바꾸기까지
01

Summary

실수는 사람이 하지만, 방어는 시스템이 한다: NPE 장애를 팀의 AI 방어벽으로 구축한 여정

지나치기 쉬운 NullPointerException을 도메인 주도 설계와 AI 에이전트 자동화 지침으로 영원히 박멸하는 방법

행복한 연차 날 아침을 깨운 쿠폰 복원 장애의 주범인 NPE(NullPointerException)를 분석하고, 이를 설계적 개선과 팀의 자동화 시스템으로 승화시킨 생생한 경험담입니다. 단순한 방어적 null 체크를 넘어 Optional, 값 객체(Value Object), 시스템 경계에서의 처리를 통해 구조적 null 안전성을 확보하는 설계 원칙을 제시합니다. 나아가 AI 에이전트인 Claude Code의 행동 지침에 장애 사례를 이식하여 사람이 개입하지 않아도 시스템이 스스로 NPE를 검증하고 예방하는 개발 파이프라인의 미래를 보여줍니다.

  • 01리팩토링 과정에서 조건문 울타리가 제거되며 발생한 운영 환경 NPE의 원인을 면밀하게 분석
  • 02단순 boolean 플래그 대신 Optional과 도메인 객체를 활용해 null 체크 누락을 컴파일 레벨에서 차단하는 설계 기법 제시
  • 03범용 유틸리티가 아닌 데이터의 소유자(Value Object)에게 null 판단 책임을 이관하는 캡슐화 원칙 설명
  • 04시스템 진입 장벽(Mapper 등)에서 null을 사전에 정제하여 도메인 내부를 안전지대로 만드는 전략
  • 05Claude Code 에이전트의 SSOT 지침에 장애 패턴 체크리스트를 반영하여 AI가 코드를 자동 검증하는 파이프라인 구축

RECOMMENDATION

자바/스프링 환경에서 반복되는 NPE 장애로 골머리를 앓는 백엔드 개발자나, 회고 후에도 자꾸만 재발하는 휴먼 에러를 시스템 및 AI 자동화로 근본적으로 해결하고 싶은 개발 팀에게 강력히 추천합니다.

The Problem

쿠폰 복원 로직 리팩토링 과정에서 예산 제한 여부를 체크하는 조건문 울타리가 사라져, 일반 쿠폰 처리 시 null 데이터가 유틸리티 함수로 유입되어 운영 환경에서 NullPointerException(NPE)이 발생하였습니다. 이는 전통적인 컴파일러 검증, 테스트 커버리지, 단순 코드 리뷰만으로는 잡아내기 어려웠던 엣지 케이스였습니다.

The Solution

Null 가능성을 단순 플래그가 아닌 Optional 타입 및 도메인 객체(값 객체)로 승격하여 컴파일 단계에서 검증을 강제하고, 시스템 경계(Mapper)에서 null을 사전 정리하도록 설계를 개선했다. 또한, 분석된 장애 패턴을 Claude Code 기반의 AI 에이전트 행동 지침(implementer.md)에 체크리스트로 자동화 등록하여 시스템적으로 재발을 방지하는 방어 체계를 구축했다.

The Result

리팩토링 이후 설계 관점에서는 null 체크 누락 실수가 원천 차단되었으며, AI 에이전트가 코드를 작성하는 과정에서 스스로 null 가드 코드를 보강하고 NPE를 사전에 탐지하여 테스트를 통과시키는 자동화된 방어 체계를 구축하는 성과를 거두었다.

Trade-off

도메인 객체와 Optional을 적극 도입함으로써 코드의 안전성과 응집도는 높아졌으나, JPA 엔티티 필드와 같이 프레임워크 제약상 Optional을 직접 사용하지 못하는 영역이 존재하여 @Nullable 어노테이션을 통한 정적 분석에 의존해야 하는 한계가 존재하며, 도메인 객체 및 값 객체(VO)의 개수가 늘어나 구조적 복잡도가 다소 증가할 수 있습니다.

03

Key Concepts

Concept · 01

값 객체 (Value Object)

도메인 주도 설계(DDD)에서 비즈니스 개념을 나타내는 불변 객체로, 단순히 데이터만 담는 것이 아니라 관련된 비즈니스 유효성 검증 및 로직을 스스로 수행하여 책임의 응집도를 높입니다.

  • 시작일과 종료일을 묶는 IssuePeriod 값 객체를 도입하여 '종료일 null은 무제한을 의미한다'는 도메인 규칙을 객체 내부에 응집함
  • 외부 유틸리티 함수에 의존하지 않고 IssuePeriod 내에서 스스로 null 여부를 판단하여 기본값을 할당하도록 개선함
Concept · 02

Optional

Java 8에 도입된 래퍼 클래스로, null이 존재할 수 있음을 타입 시스템을 통해 명시적으로 나타내어 호출자가 반드시 null 가능성을 의식하고 처리하도록 강제합니다.

  • Policy 클래스 내의 예산 정보를 Optional<Budget> 타입으로 반환하도록 변경함
  • 호출부에서 .ifPresent() 또는 .map() 체이닝을 사용하도록 강제하여 예산 검증 로직을 실수로 누락하는 시나리오를 원천 차단함
Concept · 03

AI 에이전트 파이프라인 (Claude Code)

개발 지침(SSOT)을 기반으로 기획, 테스트 작성, 구현, 코드 리뷰 등의 소프트웨어 개발 수명 주기(SDLC)를 자동 수행하는 AI 기반 워크플로우 엔진입니다.

  • 장애 분석 결과를 반영한 NPE 방어 원칙을 implementer.md 에이전트 지침 파일에 자동 체크리스트로 등록함
  • 에이전트가 코드를 스스로 검토하는 과정에서 누락된 null 가드 코드를 자동 탐지하고 보강하는 안전장치로 작동함