为何purrr::possibly未捕获tidyjson::spread_all报错?如何正确处理?
正确使用purrr::possibly处理tidyjson::spread_all的错误捕获
问题场景
尝试用purrr::possibly捕获tidyjson::spread_all执行时的错误,期望出错时返回仅含json_err列的tibble,但代码执行时仍抛出错误:
原代码:
profile_res<- log_data_to_parse %>% filter(!is.na(profile_json)) %>% rowwise() %>% extract2('profile_json') %>% possibly(tidyjson::spread_all(.),otherwise=tibble(json_err=1111111))
报错信息:
Error in `purrr::map()`: ℹ In index: 357. Caused by error in `file.exists()`: ! file name conversion problem -- name too long? Run `rlang::last_error()` to see where the error occurred.
调用栈显示错误来自tidyjson::spread_all内部的purrr::map调用,而possibly未起到捕获作用。
错误原因
purrr::possibly的用法错误:它是函数修饰器,需要传入函数本身,而非函数执行后的结果。原代码中tidyjson::spread_all(.)会先执行,出错时直接抛出错误,根本没进入possibly的错误捕获逻辑。
正确实现方式
方法1:结合purrr::map使用possibly
将spread_all包裹进possibly生成容错函数,再用map逐个处理JSON字符串:
profile_res <- log_data_to_parse %>% filter(!is.na(profile_json)) %>% pull(profile_json) %>% # 用pull替代extract2更清晰 map(possibly(tidyjson::spread_all, otherwise = tibble(json_err = 1111111))) %>% bind_rows() # 将结果合并为单个tibble
方法2:在rowwise中使用mutate
如果需要保留原数据的其他列,可以在rowwise环境中处理:
profile_res <- log_data_to_parse %>% filter(!is.na(profile_json)) %>% rowwise() %>% mutate( parsed = list(possibly(tidyjson::spread_all, otherwise = tibble(json_err = 1111111))(profile_json)) ) %>% unnest(parsed) %>% ungroup()
核心逻辑说明
purrr::possibly(f, otherwise)的作用是生成一个新函数:当调用这个新函数时,若执行f出错,就返回otherwise指定的值;若成功则返回f的执行结果。- 必须确保
possibly接收的是未执行的函数f,而不是f(x)的执行结果,否则错误会在possibly生效前就抛出。
内容的提问来源于stack exchange,提问作者user13752384
相关产品推荐
相关产品推荐

