You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

httr2::last_response()与purrr::possibly()组合使用返回NULL的问题

解决httr2::last_response()与purrr::possibly()组合时的响应捕获问题

你遇到的问题核心是purrr::possibly()的otherwise参数是在定义函数时立即求值的,不是在函数执行出错时才调用。当你写otherwise = httr2::last_response()时,这个表达式在创建safe_request的瞬间就运行了——此时还没有发送任何请求,last_response()自然返回NULL,所以出错时就会返回这个预存的NULL,而不是去获取请求后的响应。

下面提供两种可行的解决方案,以及适配purrr批量迭代的扩展方法:

思路1:用httr2内置控制避免抛出错误

httr2的req_error()可以让请求不抛出HTTP错误,直接返回完整响应对象,不管状态码。这种方式不需要依赖全局的last_response(),逻辑更清晰:

library(httr2)
library(purrr)
library(stringr)

# 定义不抛出HTTP错误的请求函数
request_without_error <- function(url) {
  url %>%
    request() %>%
    req_error(is_error = function(resp) FALSE) %>% # 所有状态码都不触发错误
    req_perform()
}

# 测试单个请求
url <- str_c("https://mutalyzer.nl/api/normalize/", "GRCh37", "(", "NM_000546.5", "):", "c.673A>T")
resp <- request_without_error(url)
resp_body_json(resp) # 直接解析422状态的响应体

思路2:在possibly中延迟获取last_response()

如果一定要保留possibly的使用,需要把otherwise改成匿名函数,让它在错误发生时才执行last_response():

# 重新定义safe_request,让otherwise延迟求值
safe_request <- possibly(
  .f = \(url) url %>% request() %>% req_perform(),
  otherwise = \(httr2::last_response()), # 用函数包裹,错误触发时才执行
  quiet = TRUE
)

# 测试
result <- safe_request(url)
resp_body_json(result) # 现在能正常获取422的响应体

适配purrr批量处理的可扩展方法

针对批量URL处理,推荐使用思路1,避免全局状态带来的意外覆盖问题,同时可以灵活处理不同状态的响应:

# 构造批量URL示例
urls <- c(
  str_c("https://mutalyzer.nl/api/normalize/", "GRCh37", "(", "NM_000546.5", "):", "c.673A>T"),
  str_c("https://mutalyzer.nl/api/normalize/", "GRCh37", "(", "NM_000546.5", "):", "c.1A>G")
)

# 批量处理并按状态码分类结果
batch_results <- urls %>%
  map(request_without_error) %>%
  map(function(resp) {
    if (resp_status(resp) == 200) {
      list(status = "success", data = resp_body_json(resp))
    } else {
      list(status = "error", code = resp_status(resp), detail = resp_body_json(resp))
    }
  })

# 查看批量处理结果
batch_results

内容的提问来源于stack exchange,提问作者PeRiKo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:35:13