---
sidebar_label: "오류 처리"
title: "오류 처리 - CyberGo html | 견고한 오류 처리 가이드"
description: "CyberGo html 오류 처리 가이드: 5 가지 오류 분류, errors.Is/As 판별, context 취소와 배치 부분 실패 처리로 견고한 로직을 구축합니다."
sidebar_position: 2
---

# 오류 처리

## 오류 분류

HTML 라이브러리의 오류는 다음과 같이 분류됩니다:

| 분류 | 센티넬 오류 | 설명 |
|------|----------|------|
| 입력 오류 | `ErrInputTooLarge`, `ErrInvalidHTML` | 입력 콘텐츠 문제 |
| 설정 오류 | `ErrInvalidConfig`, `ErrMultipleConfigs` | 설정 문제 |
| 파일 오류 | `ErrFileNotFound`, `ErrInvalidFilePath` | 파일 작업 문제 |
| 처리 오류 | `ErrProcessingTimeout`, `ErrMaxDepthExceeded` | 처리 과정 문제 |
| 시스템 오류 | `ErrProcessorClosed`, `ErrInternalPanic` | 내부 상태 문제 |

## errors.Is 패턴

`errors.Is`를 사용하여 오류 유형을 판별합니다:

```go
result, err := html.Extract(data)
if err != nil {
    switch {
    case errors.Is(err, html.ErrInputTooLarge):
        slog.Warn("입력이 너무 큽니다. 문서 크기를 줄이세요")
    case errors.Is(err, html.ErrInvalidHTML):
        slog.Warn("유효하지 않은 HTML 입니다. 입력을 확인하세요")
    case errors.Is(err, html.ErrProcessingTimeout):
        slog.Warn("처리 타임아웃. 문서가 너무 복잡할 수 있습니다")
    case errors.Is(err, html.ErrFileNotFound):
        slog.Warn("파일이 존재하지 않습니다")
    case errors.Is(err, html.ErrMaxDepthExceeded):
        slog.Warn("DOM 깊이가 너무 깊습니다. 악의적으로 구성되었을 수 있습니다")
    case errors.Is(err, html.ErrInternalPanic):
        slog.Error("내부 패닉이 복구되었습니다. 이 문제를 보고해 주세요")
    default:
        slog.Error("알 수 없는 오류", "err", err)
    }
}
```

## errors.As 패턴

구조화된 오류 정보를 추출합니다:

```go
var inputErr *html.InputError
var configErr *html.ConfigError
var fileErr *html.FileError

if errors.As(err, &inputErr) {
    fmt.Printf("크기 %d가 제한 %d를 초과함\n", inputErr.Size, inputErr.MaxSize)
}

if errors.As(err, &configErr) {
    fmt.Printf("필드 %s 값 %v이(가) 유효하지 않음: %s\n", configErr.Field, configErr.Value, configErr.Message)
}

if errors.As(err, &fileErr) {
    fmt.Printf("파일 작업: %s\n", fileErr.SafePath())
}
```

## 컨텍스트 취소

`ExtractWithContext` 버전을 사용하여 취소를 지원합니다:

```go
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

result, err := html.ExtractWithContext(ctx, data)
if err != nil {
    switch {
    case errors.Is(err, html.ErrProcessingTimeout):
        // 타임아웃 처리 (라이브러리 내 ProcessingTimeout 트리거, 이때 ctx.Err() 는 nil 일 수 있음)
    case ctx.Err() == context.DeadlineExceeded:
        // 사용자 컨텍스트 마감 시간 도달
    case ctx.Err() == context.Canceled:
        // 수동 취소
    default:
        // 기타 오류 (ErrInvalidHTML, ErrInputTooLarge 등)
        slog.Error("추출 실패", "err", err)
    }
}
```

## 배치 오류

배치 처리 결과에는 부분 성공과 부분 실패가 포함됩니다:

```go
batch := p.ExtractBatch(pages)

for i, err := range batch.Errors {
    if err != nil {
        fmt.Printf("항목 %d 실패: %v\n", i, err)
    }
}

fmt.Printf("성공: %d, 실패: %d, 취소: %d\n",
    batch.Success, batch.Failed, batch.Cancelled)
```
