使用Plumber API接收CSV生成可下载报告时遇500错误求助
问题排查与修复方案
你的Plumber API出现500错误,核心问题及对应修复方法如下:
1. 文件读取路径错误
你当前用uploaded_file1$name读取文件,但这个是客户端上传的原始文件名,文件实际临时存储路径是datapath字段,用name会导致找不到文件触发错误。
修复:将read.csv(in_file1, ...)替换为read.csv(uploaded_file1$datapath, ...),直接使用临时存储路径读取文件。
2. Multipart字段名不匹配
如果在Postman上传文件时,表单字段名不是upload(比如用了file1/file2),multipart$upload[[1]]会返回NULL,直接报错。
修复:要么确保Postman里的表单字段名统一为upload,要么把代码里的multipart$upload改成对应字段名(比如multipart$file1)。
3. 序列化器与as_attachment冲突
你同时使用了自定义的@serializer word注解和as_attachment,这会导致响应头重复设置,引发异常。
修复:二选一即可,推荐保留as_attachment(它会自动处理下载响应头),同时去掉@serializer word注解。
4. 缺少错误捕获机制
任何一步失败(文件未上传、CSV格式错误、Rmd渲染失败)都会直接返回500,无法定位具体问题。
修复:用tryCatch包裹核心逻辑,捕获错误并返回明确的错误信息。
5. 文件路径与存在性问题
- 确保
rapport_.Rmd和tmplt.docx在API工作目录下,或用绝对路径指定位置 - 生成报告时用临时文件路径,避免文件覆盖或权限问题
修正后的完整代码
#* 生成报告 #* @post /generate_report_from_data upload <- function(req, res) { tryCatch({ # 解析多部分表单数据 multipart <- mime::parse_multipart(req) # 检查文件数量与字段名 if (is.null(multipart$upload) || length(multipart$upload) < 2) { res$status <- 400 return(list(error = "请上传两个CSV文件,表单字段名需为'upload'")) } # 读取上传的CSV文件 df <- read.csv(multipart$upload[[1]]$datapath, header = TRUE, sep = ";") df_bbl <- read.csv(multipart$upload[[2]]$datapath, header = TRUE, sep = ";") # 数据编码处理(确保data_recoding函数已定义) df <- data_recoding(df, df_bbl, sep = ",") # 生成临时输出文件路径,避免冲突 output_path <- tempfile(fileext = ".docx") # 渲染Word报告 rmarkdown::render( input = "rapport_.Rmd", output_file = basename(output_path), output_dir = dirname(output_path), output_format = rmarkdown::word_document(reference_docx = "tmplt.docx"), params = list(team1 = df, team2 = df_bbl) ) # 读取文件内容并返回可下载附件 file_content <- readBin(output_path, "raw", n = file.info(output_path)$size) res$status <- 200 as_attachment(file_content, "rapport.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") }, error = function(e) { res$status <- 500 list(error = paste("服务器错误:", e$message)) }) }
Postman请求设置
- 选择
POST方法,填写API地址(如http://localhost:8000/generate_report_from_data) - 切换到
Body标签,选择form-data类型 - 添加两个键,键名均为
upload,类型选择File,分别上传目标CSV文件 - 发送请求,正常情况下会返回可下载的docx报告
内容的提问来源于stack exchange,提问作者Akram HECINI
相关产品推荐
相关产品推荐

