0Pricing
R Academy · レッスン

エラー回復のためのtryCatch()

tryCatch()でエラー、警告、メッセージを捕捉して処理します。

「エラー回復のためのtryCatch()」はCoddyKit上の無料R Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。

tryCatch()とは

tryCatch()を使うと、式を実行し、その式が通知するコンディション(エラー、警告、メッセージ)を捕捉できます。式が成功すれば、その値が返されます。コンディションが通知された場合は、該当するハンドラーが代わりに呼び出されます。

result <- tryCatch({
  sqrt(16)
}, error = function(e) {
  NA
})
cat('Result:', result, '\n')

エラーを捕捉する

tryCatch()内の式がstop()を呼び出すと、実行はerrorハンドラーに移ります。ハンドラーはコンディションオブジェクトを受け取り、その戻り値がtryCatch()呼び出し全体の結果になります。

safe_divide <- function(x, y) {
  tryCatch({
    if (y == 0) stop('division by zero')
    x / y
  }, error = function(e) {
    cat('Caught error:', conditionMessage(e), '\n')
    NA
  })
}
cat(safe_divide(10, 2), '\n')
cat(safe_divide(10, 0), '\n')

警告を捕捉する

warningハンドラーもerrorハンドラーと同じように機能しますが、警告コンディションを捕捉します。注意点として、tryCatch()内でwarningハンドラーを定義すると、警告によってエラーと同様に非局所的な終了が発生し、警告の後から実行を再開することはありません。

result <- tryCatch({
  log(-1)
}, warning = function(w) {
  cat('Warning caught:', conditionMessage(w), '\n')
  -999
})
cat('Result:', result, '\n')

メッセージを捕捉する

message()の条件も捕捉できます。これにより、制御できない関数からの情報出力を横取りして、形式を整え直せます。ハンドラーは条件オブジェクトを受け取り、メッセージのテキストには末尾の改行が含まれます。

result <- tryCatch({
  message('Loading data...')
  42
}, message = function(m) {
  cat('Intercepted message:', trimws(conditionMessage(m)), '\n')
  -1
})
cat('Result:', result, '\n')

finally節

finallyブロックは、式が成功したか、エラーになったか、警告が出たかにかかわらず、式の後に必ず実行されます。接続を閉じる、オプションをリセットする、完了をログに記録するといった後処理のコードに使用します。

result <- tryCatch({
  cat('Trying...\n')
  stop('oops')
}, error = function(e) {
  cat('Handled:', e$message, '\n')
  -1
}, finally = {
  cat('Finally block always runs\n')
})
cat('Result:', result, '\n')

複数のハンドラー

1回のtryCatch()呼び出しで、複数の条件型に対するハンドラーを指定できます。Rは最初に適用可能なハンドラーを使用します。errorとwarningの両方のハンドラーが定義されている場合、警告はエラーになる前に捕捉されます。

handle_it <- function(expr_result) {
  tryCatch(expr_result,
    error   = function(e) paste('ERROR:', e$message),
    warning = function(w) paste('WARN:', w$message),
    message = function(m) paste('MSG:', trimws(m$message))
  )
}
cat(handle_it(stop('bad input')), '\n')
cat(handle_it(log(-1)), '\n')

ループ内でのエラー回復

非常に実用的なパターンとして、ループ本体をtryCatch()で囲む方法があります。これにより、1回の反復で失敗してもループ全体が停止しません。予測不能な失敗が起こり得るファイル、API呼び出し、ユーザー入力を処理する場合に不可欠です。

inputs <- list(4, -1, 0, 16, 'x')
results <- vector('list', length(inputs))
for (i in seq_along(inputs)) {
  results[[i]] <- tryCatch(
    sqrt(as.numeric(inputs[[i]])),
    warning = function(w) NA,
    error   = function(e) NA
  )
}
cat('Results:', unlist(results), '\n')

エラー時に意味のあるデフォルト値を返す

エラーハンドラーから妥当なデフォルト値を返すのが、すっきりしたパターンです。ハンドラーの戻り値がtryCatch()の結果になります。NA、NULL、0、またはデフォルトのリストを返すとうまく機能します。

safe_parse <- function(x) {
  tryCatch(
    as.numeric(x),
    warning = function(w) {
      cat('Cannot parse:', x, '-> using 0\n')
      0
    }
  )
}
cat(safe_parse('3.14'), '\n')
cat(safe_parse('abc'), '\n')
cat(safe_parse('99'), '\n')

エラーメッセージを取り出す

エラーハンドラー内では、conditionMessage(e)または短縮形のe$messageを使用してエラーテキストを取得します。エラーを引き起こした呼び出しを取得するには、conditionCall(e)またはe$callを使用します。

tryCatch(
  stop('file not found: data.csv'),
  error = function(e) {
    cat('Message:', conditionMessage(e), '\n')
    cat('Class  :', paste(class(e), collapse=', '), '\n')
  }
)

tryCatch()とtry()の比較

Rには、より単純なtry(expr)関数もあります。エラーが発生すると、処理を停止する代わりに、クラス'try-error'のオブジェクトを返します。簡単な1行の処理にはtry()を、ハンドラーを完全に制御したい場合やfinallyブロックが必要な場合にはtryCatch()を使用します。

# try() returns try-error object on failure
result <- try(log('x'), silent = TRUE)
if (inherits(result, 'try-error')) {
  cat('try() caught error\n')
} else {
  cat('Result:', result, '\n')
}

tryCatch()呼び出しのネスト

tryCatch()呼び出しはネストできます。内側のtryCatch()が先に条件を捕捉します。内側でstop(e)を使用して再スローすると、外側のハンドラーが再スローされた条件を捕捉します。

outer_result <- tryCatch({
  tryCatch({
    stop('inner error')
  }, error = function(e) {
    cat('Inner handler, re-throwing\n')
    stop(paste('Wrapped:', e$message))
  })
}, error = function(e) {
  cat('Outer handler:', e$message, '\n')
  'recovered'
})
cat('Final:', outer_result, '\n')

確認問題

tryCatch()では、エラーが発生したかどうかにかかわらず、どの節が必ず実行されますか?

tryCatch(): 重要なポイント

tryCatch()の重要なポイント:

  • error = function(e) {...}でエラーを、warning = function(w) {...}で警告を捕捉します
  • ハンドラーの戻り値がtryCatch()の結果になります
  • finallyは必ず実行されるため、後処理に適しています
  • 信頼できない入力を反復処理する場合は、ループ本体をtryCatch()で囲むと堅牢になります
  • e$messageまたはconditionMessage(e)でエラーテキストを取り出せます
  • try(expr, silent=TRUE)は、より単純な1行の代替手段です
safe_op <- function(x) {
  tryCatch({
    if (!is.numeric(x)) stop('not numeric')
    sqrt(x)
  }, error = function(e) {
    cat('Error:', e$message, '\n')
    NA
  }, finally = {
    cat('Done processing', x, '\n')
  })
}
cat(safe_op(9), '\n')
cat(safe_op('a'), '\n')

よくある質問

「エラー回復のためのtryCatch()」レッスンは無料ですか?

はい。「エラー回復のためのtryCatch()」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。

「エラー回復のためのtryCatch()」で何を学びますか?

tryCatch()でエラー、警告、メッセージを捕捉して処理します。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

R Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「エラー回復のためのtryCatch()」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このR Academyレッスンでコードを書いて実行できますか?

はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Rのエラー、警告、メッセージ
  2. エラー回復のためのtryCatch()
  3. withCallingHandlers()と再起動
  4. stop()とwarning()による堅牢な関数の作成
← R Academyに戻る