MCP HubMCP Hub
스킬 목록으로 돌아가기

fail-early-pattern

pjt222
업데이트됨 Yesterday
3 조회
17
2
17
GitHub에서 보기
테스팅aiapidesign

정보

이 스킬은 개발자가 가드 절과 명확한 메시지를 사용하여 입력을 검증하고 오류를 즉시 포착하는 빠른 실패 패턴을 구현하도록 돕습니다. R 언어의 실용적인 예시와 함께 함수 및 API를 견고하게 만드는 교차 언어 원칙을 제공합니다. 외부 입력을 처리하는 코드를 작성하거나 리팩터링할 때, 무음 실패를 방지하고 오류 처리 품질을 향상시키기 위해 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/fail-early-pattern

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

早敗

將敗者宜早敗、明敗、附最多脈。此技定早敗之模:於系界驗入、以守句拒壞態於傳前、書答敗、何處何以如何修之誤訊。

用時

  • 書或審受外入(用數、API 應、文容)之函
  • CRAN 提前加包函之入驗
  • 重構默生誤果之碼
  • 審 PR 之誤處之質
  • 強內 API 之抗壞參

  • 必要:欲施此模之函或模
  • 必要:信界之識(外數何入)
  • 可選:欲重構之既誤處碼
  • 可選:目語(默 R;亦適 Python、TypeScript、Rust)

第一步:識信界

映外數入系之處。此乃需驗之點:

  • 公 API 函(R 包中出函)
  • 用面參
  • 文 I/O(讀配、數文、用上傳)
  • 網應(API 呼、庫詢)
  • 環變與系配

唯汝已驗碼呼之內輔函通常無需重驗。

得: 不信數入汝碼之入點之列。

敗則: 若界不明,自日或缺報之誤反溯以尋壞數首入處。

第二步:於入點加守句

於各公函頂驗入,於工始前。

R(基):

calculate_summary <- function(data, method = c("mean", "median", "trim"), trim_pct = 0.1) {
  # Guard: type check
  if (!is.data.frame(data)) {
    stop("'data' must be a data frame, not ", class(data)[[1]], call. = FALSE)
  }
  # Guard: non-empty
  if (nrow(data) == 0L) {
    stop("'data' must have at least one row", call. = FALSE)
  }
  # Guard: argument matching
  method <- match.arg(method)
  # Guard: range check
  if (!is.numeric(trim_pct) || trim_pct < 0 || trim_pct > 0.5) {
    stop("'trim_pct' must be a number between 0 and 0.5, got: ", trim_pct, call. = FALSE)
  }
  # --- All guards passed, begin real work ---
  # ...
}

R(rlang/cli——包宜用):

calculate_summary <- function(data, method = c("mean", "median", "trim"), trim_pct = 0.1) {
  rlang::check_required(data)
  if (!is.data.frame(data)) {
    cli::cli_abort("{.arg data} must be a data frame, not {.cls {class(data)}}.")
  }
  if (nrow(data) == 0L) {
    cli::cli_abort("{.arg data} must have at least one row.")
  }
  method <- rlang::arg_match(method)
  if (!is.numeric(trim_pct) || trim_pct < 0 || trim_pct > 0.5) {
    cli::cli_abort("{.arg trim_pct} must be between 0 and 0.5, not {.val {trim_pct}}.")
  }
  # ...
}

通(TypeScript):

function calculateSummary(data: DataFrame, method: Method, trimPct: number): Summary {
  if (data.rows.length === 0) {
    throw new Error(`data must have at least one row`);
  }
  if (trimPct < 0 || trimPct > 0.5) {
    throw new RangeError(`trimPct must be between 0 and 0.5, got: ${trimPct}`);
  }
  // ...
}

得: 諸公函首守句,拒壞入於任何副效或算前。

敗則: 若驗邏長(守逾十五行),析 validate_* 輔或用 stopifnot() 為簡型斷。

第三步:書義誤訊

每誤訊當答四問:

  1. 敗——何參或操
  2. 何處——函名或脈(cli::cli_abort 自動)
  3. 何以——預何對受何
  4. 如何修——若修非顯

善訊:

# What + Why (expected vs. actual)
stop("'n' must be a positive integer, got: ", n, call. = FALSE)

# What + Why + How to fix
cli::cli_abort(c(
  "{.arg config_path} does not exist: {.file {config_path}}",
  "i" = "Create it with {.run create_config({.file {config_path}})}."
))

# What + context
cli::cli_abort(c(
  "Column {.val {col_name}} not found in {.arg data}.",
  "i" = "Available columns: {.val {names(data)}}"
))

惡訊:

stop("Error")                    # What failed? No idea
stop("Invalid input")           # Which input? What's wrong with it?
stop(paste("Error in step", i)) # No actionable information

得: 誤訊自證——初見誤者可診而修,不讀源。

敗則: 察近三缺報。若任一需讀源方解,其誤訊須改。

第四步:偏 stop() 於 warning()

stop()(或 cli::cli_abort())於函不能生正果時。用 warning() 唯函仍能生有義果而呼者當知之憂。

要則: 若用或默得誤答,乃 stop(),非 warning()

# CORRECT: stop when result would be wrong
read_config <- function(path) {
  if (!file.exists(path)) {
    stop("Config file not found: ", path, call. = FALSE)
  }
  yaml::read_yaml(path)
}

# CORRECT: warn when result is still usable
summarize_data <- function(data) {
  if (any(is.na(data$value))) {
    warning(sum(is.na(data$value)), " NA values dropped from 'value' column", call. = FALSE)
    data <- data[!is.na(data$value), ]
  }
  # proceed with valid data
}

得: stop() 用於將生誤果之況;warning() 留於降質但有效之果。

敗則: 察既 warning() 呼。若警後函返無義,改為 stop()

第五步:以斷之內不變

於正碼中「不當生」之況用斷。於開發時捕程誤:

# R: stopifnot for internal invariants
process_chunk <- function(chunk, total_size) {
  stopifnot(
    is.list(chunk),
    length(chunk) > 0,
    total_size > 0
  )
  # ...
}

# R: explicit assertion with context
merge_results <- function(left, right) {
  if (ncol(left) != ncol(right)) {
    stop("Internal error: column count mismatch (", ncol(left), " vs ", ncol(right),
         "). This is a bug — please report it.", call. = FALSE)
  }
  # ...
}

得: 內不變以斷,缺於違處立現,非三呼後以謎誤。

敗則:stopifnot() 訊過謎,改以明 if/stop 附脈。

第六步:重構反模

識並修此常反模:

反模一:空 tryCatch(吞誤)

# BEFORE: Error silently disappears
result <- tryCatch(
  parse_data(input),
  error = function(e) NULL
)

# AFTER: Log, re-throw, or return a typed error
result <- tryCatch(
  parse_data(input),
  error = function(e) {
    cli::cli_abort("Failed to parse input: {e$message}", parent = e)
  }
)

反模二:默值遮壞入

# BEFORE: Caller never knows their input was ignored
process <- function(x = 10) {
  if (!is.numeric(x)) x <- 10  # silently replaces bad input
  x * 2
}

# AFTER: Tell the caller about the problem
process <- function(x = 10) {
  if (!is.numeric(x)) {
    stop("'x' must be numeric, got ", class(x)[[1]], call. = FALSE)
  }
  x * 2
}

反模三:suppressWarnings 為修

# BEFORE: Hiding the symptom instead of fixing the cause
result <- suppressWarnings(as.numeric(user_input))

# AFTER: Validate explicitly, handle the expected case
if (!grepl("^-?\\d+\\.?\\d*$", user_input)) {
  stop("Expected a number, got: '", user_input, "'", call. = FALSE)
}
result <- as.numeric(user_input)

反模四:統括之異處

# BEFORE: Every error treated the same
tryCatch(
  complex_operation(),
  error = function(e) message("Something went wrong")
)

# AFTER: Handle specific conditions, let unexpected ones propagate
tryCatch(
  complex_operation(),
  custom_validation_error = function(e) {
    cli::cli_warn("Validation issue: {e$message}")
    fallback_value
  }
  # Unexpected errors propagate naturally
)

得: 反模以明驗或具體誤處代之。

敗則: 若去 tryCatch 致連敗,上游碼有驗缺。修源,非症。

第七步:驗早敗重構

運試集以確誤徑正工:

# Verify error messages are triggered
testthat::expect_error(calculate_summary("not_a_df"), "must be a data frame")
testthat::expect_error(calculate_summary(data.frame()), "at least one row")
testthat::expect_error(calculate_summary(mtcars, trim_pct = 2), "between 0 and 0.5")

# Verify valid inputs still work
testthat::expect_no_error(calculate_summary(mtcars, method = "mean"))
# Run full test suite
Rscript -e "devtools::test()"

得: 諸試過。誤徑試確壞入觸預誤訊。

敗則: 若既試賴默敗(如壞入返 NULL),更之以預新誤。

  • 諸公函於工前驗入
  • 誤訊答:何敗、何處、何以、如何修
  • stop() 用於生誤果之況
  • warning() 唯用於降質有效之果
  • 無默吞誤之空 tryCatch
  • suppressWarnings() 代正驗
  • 無默遮壞入之默值
  • 內不變用 stopifnot() 或明斷
  • 各驗守有誤徑試
  • 重構後試集過

  • 驗過深:於信界(公 API)驗,非諸內輔。過驗加噪損性能
  • 無脈之誤訊:「Invalid input」迫呼者猜。恆含參名、預類/域、實收值
  • 當用 stop() 時用 warning():若警後函返垃圾,呼者默得誤答。用 stop(),令呼者決如何處
  • tryCatch 吞誤tryCatch(..., error = function(e) NULL) 藏缺。若必捕,記或附脈重擲
  • 忘 call. = FALSE:R 中 stop("msg") 默含呼,於用顯噪。用面函用 call. = FALSEcli::cli_abort() 自動
  • 於試驗而非碼:試驗行而不護產呼者。驗屬函本
  • 雜系誤 R 本:於 WSL 或 Docker,Rscript 或解至跨平台包而非原 R。以 which Rscript && Rscript --version 察。偏原 R(如 Linux/WSL 之 /usr/local/bin/Rscript)以穩。見 Setting Up Your Environment 之 R 路配

  • write-testthat-tests - 書驗誤徑之試
  • review-pull-request - 審碼缺驗與默敗
  • review-software-architecture - 於系級評誤處策
  • create-skill - 循 agentskills.io 標造新技
  • security-audit-codebase - 與入驗疊之安全審

GitHub 저장소

pjt222/agent-almanac
경로: i18n/wenyan/skills/fail-early-pattern
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

evaluating-llms-harness

테스팅

이 Claude Skill은 MMLU, GSM8K를 포함한 60개 이상의 표준화된 학술 과제에서 LLM 성능을 벤치마크하기 위해 lm-evaluation-harness를 실행합니다. 개발자들이 모델 품질을 비교하고, 학습 진행 상황을 추적하거나 학술 결과를 보고할 수 있도록 설계되었습니다. 이 도구는 HuggingFace와 vLLM 모델을 포함한 다양한 백엔드를 지원합니다.

스킬 보기

cloudflare-cron-triggers

테스팅

이 스킬은 cron 표현식을 사용하여 Worker를 스케줄링하기 위한 Cloudflare Cron Triggers 구현에 관한 포괄적인 지식을 제공합니다. 주기적 작업, 유지보수 작업, 자동화된 워크플로우 설정 방법을 다루며, 잘못된 cron 표현식이나 시간대 문제 같은 일반적인 이슈들을 해결하는 방법을 포함합니다. 개발자들은 이를 통해 스케줄된 핸들러 구성, cron 트리거 테스트, Workflows 및 Green Compute와의 연동 작업을 수행할 수 있습니다.

스킬 보기

webapp-testing

테스팅

이 Claude Skill은 Python 스크립트를 통해 로컬 웹 애플리케이션을 테스트하기 위한 Playwright 기반 툴킷을 제공합니다. 프론트엔드 검증, UI 디버깅, 스크린샷 캡처, 로그 확인 기능을 지원하며 서버 라이프사이클을 관리합니다. 브라우저 자동화 작업에 사용하되 컨텍스트 오염을 방지하기 위해 소스 코드를 읽지 않고 스크립트를 직접 실행하세요.

스킬 보기

finishing-a-development-branch

테스팅

이 스킬은 테스트 통과를 확인한 후 체계적인 통합 옵션을 제시하여 개발자가 완성된 작업을 마무리하도록 돕습니다. 구현이 완료된 후 머지, PR 생성, 브랜치 정리와 같은 워크플로우를 안내합니다. 코드가 준비되고 테스트가 완료되었을 때 개발 프로세스를 체계적으로 마무리하기 위해 사용하세요.

스킬 보기