如何在R脚本出错时暂停?API报错时用sys.sleep及tryCatch的疑问
回答:是的,
tryCatch 是实现这个需求的理想方案 完全可以用 tryCatch 来捕获API请求抛出的错误(比如你遇到的HTTP 429速率限制错误),并在捕获到错误时执行 sys.sleep() 暂停脚本,甚至可以加上重试逻辑让脚本自动重新尝试请求。
基础实现示例
先给你一个最基础的版本,捕获429错误后暂停一段时间并重新请求:
library(jsonlite) # 封装API请求逻辑 fetch_api_data <- function(api_url) { tryCatch( expr = { # 尝试发起API请求 data <- fromJSON(api_url) return(data) }, error = function(e) { # 判断是否是目标429错误 if (grepl("HTTP error 429", e$message)) { message("触发API速率限制,暂停10秒后重试...") Sys.sleep(10) # 递归调用函数重新发起请求 return(fetch_api_data(api_url)) } else { # 其他类型错误直接抛出,不处理 stop(e) } } ) } # 调用函数获取数据 data <- fetch_api_data("https://api.com")
进阶优化:限制重试次数 + 动态等待时间
上面的递归可能会无限重试,建议加上重试次数限制;另外很多API返回429错误时,会在响应头里携带 Retry-After 字段,明确告知需要等待的秒数,我们可以利用这个字段来动态设置暂停时间:
library(jsonlite) library(httr) # 用于获取响应头信息 fetch_api_data <- function(api_url, max_retries = 3) { for (retry_count in 1:max_retries) { tryCatch( expr = { # 用httr发送请求,方便获取响应头 response <- GET(api_url) stop_for_status(response) # 主动触发HTTP错误 data <- fromJSON(content(response, "text")) return(data) }, error = function(e) { if (grepl("HTTP error 429", e$message) && retry_count < max_retries) { # 提取Retry-After值,没有则默认等待10秒 wait_time <- as.integer(headers(response)$`retry-after`) %||% 10 message(sprintf("第%d次触发速率限制,等待%d秒后重试...", retry_count, wait_time)) Sys.sleep(wait_time) } else { stop(sprintf("API请求失败,已尝试%d次:%s", retry_count, e$message)) } } ) } } # 调用函数获取数据 data <- fetch_api_data("https://api.com")
核心逻辑说明
tryCatch的error参数可以精准捕获fromJSON或stop_for_status抛出的异常,让你能自定义错误处理流程。- HTTP 429错误是典型的速率限制提示,暂停后重试是最贴合场景的解决方案。
- 加上重试次数限制,可以避免脚本因持续触发错误而无限循环。
内容的提问来源于stack exchange,提问作者ML_Enthousiast




