0Pricing
R Academy · บทเรียน

tryCatch() สำหรับการกู้คืนจากข้อผิดพลาด

ดักจับและจัดการข้อผิดพลาด คำเตือน และข้อความด้วย tryCatch()

tryCatch() สำหรับการกู้คืนจากข้อผิดพลาด เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน 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 แต่ดักจับเงื่อนไขคำเตือน โปรดทราบว่าเมื่อกำหนดตัวจัดการ warning ใน tryCatch() แล้ว คำเตือนจะทำให้เกิดการออกจากบริบทแบบไม่ใช่ตำแหน่งเดิมเช่นเดียวกับข้อผิดพลาด การทำงานจะไม่กลับมาดำเนินต่อหลังคำเตือน

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')

ตัวจัดการหลายตัว

คุณสามารถกำหนดตัวจัดการสำหรับประเภทเงื่อนไขหลายประเภทภายในการเรียก 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() เพื่อไม่ให้การทำซ้ำครั้งหนึ่งที่ล้มเหลวหยุดลูปทั้งหมด วิธีนี้จำเป็นอย่างยิ่งเมื่อประมวลผลไฟล์ การเรียก 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' แทนการหยุดทำงาน ใช้ try() สำหรับคำสั่งสั้น ๆ บรรทัดเดียว และใช้ tryCatch() เมื่อต้องควบคุมตัวจัดการอย่างเต็มรูปแบบหรือจำเป็นต้องมีบล็อก finally

# 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) เป็นทางเลือกแบบคำสั่งสั้น ๆ บรรทัดเดียวที่ง่ายกว่า
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() สำหรับการกู้คืนจากข้อผิดพลาด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “tryCatch() สำหรับการกู้คืนจากข้อผิดพลาด”

ดักจับและจัดการข้อผิดพลาด คำเตือน และข้อความด้วย tryCatch() คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “tryCatch() สำหรับการกู้คืนจากข้อผิดพลาด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม

ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ข้อผิดพลาด คำเตือน และข้อความใน R
  2. tryCatch() สำหรับการกู้คืนจากข้อผิดพลาด
  3. withCallingHandlers() และการเริ่มทำงานใหม่
  4. การเขียนฟังก์ชันที่ทนทานด้วย stop() และ warning()
← กลับไปที่ R Academy