askill
debugging

debuggingSafety --Repository

디버깅 전략, 로깅 베스트 프랙티스, 에러 추적

0 stars
1.2k downloads
Updated 1/24/2026

Package Files

Loading files...
SKILL.md

Debugging Guide

디버깅 접근법

과학적 디버깅

1. 문제 정의: 무엇이 잘못되었는가?
2. 가설 수립: 원인이 무엇일 수 있는가?
3. 실험 설계: 가설을 어떻게 검증할 것인가?
4. 실험 실행: 테스트 수행
5. 결과 분석: 가설이 맞았는가?
6. 반복 또는 수정

이분 탐색 디버깅

# 문제 범위를 절반씩 좁혀가기

# 1. 중간 지점에 로그 추가
function processOrder(order):
    validate(order)
    print("DEBUG: after validate")  # 여기까지 왔나?
    
    calculate(order)
    print("DEBUG: after calculate")
    
    save(order)
    print("DEBUG: after save")

# 2. 문제 지점 발견 후 해당 함수 내부로 이동
# 3. 반복

고무 오리 디버깅

문제를 말로 설명하면서 해결책 발견

1. 문제를 처음부터 설명한다
2. 코드가 무엇을 해야 하는지 설명한다
3. 코드가 실제로 무엇을 하는지 설명한다
4. 차이점을 발견한다

에러 유형별 접근

Null/Undefined 에러

# 증상
TypeError: Cannot read property 'x' of undefined

# 디버깅
1. 스택 트레이스에서 라인 확인
2. 해당 변수가 어디서 오는지 추적
3. 경계 조건 확인 (빈 배열, null 응답 등)

# 방어적 코딩
user = getUser(id)
if not user:
    throw UserNotFoundError(id)

name = user?.profile?.name ?? "Unknown"

비동기 에러

# 증상
- 순서가 예상과 다름
- 가끔만 발생
- 콜백이 실행되지 않음

# 디버깅
async function fetchData():
    print("1. 시작")
    response = await fetch(url)
    print("2. 응답 받음")
    data = await response.json()
    print("3. 파싱 완료")
    return data

# 일반적인 실수
# Bad: await 누락
data = fetchData()  # Promise 객체가 반환됨

# Good
data = await fetchData()

상태 관련 버그

# 증상
- 특정 순서로만 발생
- 재현이 어려움
- "새로고침하면 됨"

# 디버깅
1. 상태 변경 지점 로깅
function setState(newState):
    print("State changed:", oldState, "→", newState)
    print("Call stack:", getStackTrace())

2. 타임라인 만들기
[0ms] 초기 상태: {count: 0}
[100ms] 버튼 클릭 → {count: 1}
[150ms] API 응답 → {count: 0}  # 문제!

3. 불변성 확인
# Bad: 직접 수정
state.items.push(newItem)

# Good: 새 객체 생성
state = {...state, items: [...state.items, newItem]}

성능 문제

# 증상
- 느림
- 메모리 사용량 증가
- CPU 사용량 높음

# 디버깅 도구
- 프로파일러
- 메모리 스냅샷
- 네트워크 탭

# 측정 코드
start = performance.now()
expensiveOperation()
duration = performance.now() - start
print(f"Operation took {duration}ms")

로깅 베스트 프랙티스

로그 레벨

DEBUG   # 개발 중 상세 정보
INFO    # 정상 동작 기록
WARN    # 잠재적 문제
ERROR   # 실제 에러
FATAL   # 시스템 중단 에러

# 예시
logger.debug("Processing item", {itemId, step: 1})
logger.info("Order completed", {orderId, total})
logger.warn("Retry attempt", {attempt: 3, maxAttempts: 5})
logger.error("Payment failed", {orderId, error})

구조화된 로깅

# Bad: 문자열 연결
print("User " + userId + " purchased " + productId)

# Good: 구조화된 로그
logger.info("Purchase completed", {
    userId: userId,
    productId: productId,
    amount: amount,
    timestamp: now(),
    correlationId: requestId
})

컨텍스트 정보

# 요청 추적
function middleware(request, next):
    requestId = generateId()
    logger.setContext({requestId, userId: request.user?.id})
    
    logger.info("Request started", {
        method: request.method,
        path: request.path
    })
    
    response = next(request)
    
    logger.info("Request completed", {
        status: response.status,
        duration: getDuration()
    })
    
    return response

에러 추적

에러 경계

# 에러를 적절한 수준에서 처리

# Bad: 모든 에러 무시
try:
    doSomething()
catch:
    pass

# Good: 적절한 처리
try:
    result = riskyOperation()
catch ValidationError as e:
    logger.warn("Validation failed", {error: e})
    return BadRequest(e.message)
catch NetworkError as e:
    logger.error("Network error", {error: e})
    raise ServiceUnavailable()
catch Exception as e:
    logger.error("Unexpected error", {error: e})
    alertOncall(e)
    raise

에러 컨텍스트 추가

# Bad: 원본 에러만
throw error

# Good: 컨텍스트 추가
throw new Error("Failed to process order", {
    cause: error,
    context: {
        orderId: orderId,
        step: "payment",
        attempt: retryCount
    }
})

스택 트레이스 읽기

Error: Cannot read property 'name' of undefined
    at getFullName (user.js:25:15)        ← 실제 에러 위치
    at formatUser (formatter.js:42:10)     ← 호출한 곳
    at processUsers (processor.js:18:5)    ← 그 전 호출
    at main (index.js:10:1)                ← 시작점

읽는 방법:
1. 첫 줄: 에러 메시지
2. 두 번째 줄: 에러 발생 위치
3. 나머지: 호출 스택 (위에서 아래로 따라가기)

재현 가능한 버그 만들기

최소 재현 케이스

# 원래 코드: 1000줄
# 버그가 발생하는 최소 코드 찾기

# Step 1: 코드 절반 제거 → 버그 발생?
# Step 2: 반복
# Step 3: 최소 재현 케이스 도출

# 예시: 최소 재현
const data = null
data.toString()  // TypeError

테스트로 재현

test "reproduces the bug":
    # Given: bug condition
    user = createUser(age=17)
    
    # When: trigger bug
    result = purchaseAlcohol(user)
    
    # Then: expected behavior (currently fails)
    assert result.error == "Age verification required"

디버깅 체크리스트

시작 전

  • 문제를 명확히 정의했는가?
  • 재현 조건을 파악했는가?
  • 최근 변경사항을 확인했는가?

진행 중

  • 가설을 세웠는가?
  • 한 번에 하나만 변경하는가?
  • 변경사항을 기록하는가?

해결 후

  • 근본 원인을 이해했는가?
  • 테스트를 추가했는가?
  • 비슷한 문제가 있는지 확인했는가?

관련 스킬

  • testing: 버그 재현 테스트 작성
  • code-quality: 에러 처리 원칙
  • performance: 성능 문제 디버깅

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

AI review pending.

Metadata

Licenseunknown
Version-
Updated1/24/2026
Publisherjaeyeonling

Tags

apilintingtesting