Menu
CoddyTech

Phát sinh lỗi với stop()

Thuộc phần Logic và luồng điều khiển trong hành trình R của Coddy. Bài học 52 trên 64.

stop("message") gây ra lỗi: hàm dừng ngay lập tức, các câu lệnh phía sau không chạy và R in ra thông báo. Hãy dùng khi hàm nhận đầu vào mà nó không thể xử lý:

check_qty <- function(q) {
  if (q <= 0) stop("quantity must be positive")
  q
}
print(check_qty(3))
print(check_qty(-1))
print("never printed")

Đầu ra:

[1] 3
Error in check_qty(-1) : quantity must be positive
Calls: print -> check_qty
Execution halted

Văn bản lỗi cho biết lời gọi nào gặp lỗi, còn Execution halted nghĩa là toàn bộ script đã dừng: print() cuối cùng chưa bao giờ chạy. Lỗi được ghi vào luồng lỗi, không phải đầu ra thông thường, vì vậy trên Coddy, một test sẽ thất bại khi có bất kỳ lỗi hoặc cảnh báo nào được in ra.

stopifnot() kiểm tra nhiều điều kiện cùng lúc và báo lỗi với điều kiện đầu tiên có giá trị FALSE. Điều kiện có tên sẽ dùng tên đó làm thông báo:

area <- function(w, h) {
  stopifnot("width must be positive" = w > 0, "height must be positive" = h > 0)
  w * h
}
print(area(2, 3))
print(area(2, -1))

Đầu ra:

[1] 6
Error in area(2, -1) : height must be positive
Calls: print -> area -> stopifnot
Execution halted

Hãy tạo thông báo từ các giá trị bằng paste0() hoặc sprintf(), để người đọc thấy vấn đề nằm ở đâu:

get_item <- function(items, i) {
  if (i > length(items)) stop(sprintf("index %d is past the end (%d items)", i, length(items)))
  items[i]
}
print(get_item(c("a", "b"), 5))

Đầu ra:

Error in get_item(c("a", "b"), 5) : index 5 is past the end (2 items)
Calls: print -> get_item
Execution halted

Phát sinh lỗi ngay khi bắt đầu hàm (function), trước khi thực hiện bất kỳ thao tác nào. Các bước kiểm tra dừng sớm giúp phần còn lại của hàm đơn giản hơn, vì hàm có thể giả định đầu vào hợp lệ:

withdraw <- function(balance, amount) {
  if (amount <= 0) stop("amount must be positive")
  if (amount > balance) stop("insufficient funds")
  balance - amount
}
challenge icon

Thử thách

Dễ

Hoàn thiện make_order(item, qty, stock). Dùng stop() để báo lỗi:

  • quantity must be at least 1 khi qty nhỏ hơn 1
  • only <stock> left khi qty lớn hơn stock, chẳng hạn như only 3 left

Nếu không, trả về ordered <qty> x <item>.

Code được cung cấp sẽ đọc mặt hàng, số lượng và lượng hàng tồn kho, gọi hàm của bạn rồi in ra kết quả hoặc Error: kèm theo thông báo lỗi, vì vậy không có test nào hiển thị thông báo lỗi riêng của R.

Tự làm thử

make_order <- function(item, qty, stock) {
  # Viết code của bạn ở đây
  ""
}

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
result <- tryCatch(make_order(input[1], as.numeric(input[2]), as.numeric(input[3])),
                   error = function(e) paste("Error:", conditionMessage(e)))
cat(result, sep = "\n")
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch R online