news 2026/9/28 20:16:42

Xberg Dart 批量提取容错实战:extract_batch 处理全部缺失 URI 输入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Xberg Dart 批量提取容错实战:extract_batch 处理全部缺失 URI 输入
  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

导读

当一批待提取的文档 URI 全部指向不存在的文件(如路径拼写错误、文件已被迁移或删除)时,Xberg 的批量提取 APIextract_batch不会抛出异常终止整个任务,而是把每个失败折叠为一条结构化错误,在返回的summary中给出精确的results与errors计数。本文以 Xberg 仓库中 Dart 绑定的一则官方夹具(fixture)为核心,逐行拆解这段 Dart 代码,并深入 Rust 引擎源码,说明"全部失败"场景下的内部行为、结果类型设计,以及在实际批量处理中如何利用summary与错误明细做容错与审计。

场景:一个"全数落空"的批量输入

本篇文章讲解的夹具位于 docs-site/src/snippets-generated/dart/batch/extract_batch_uri_all_missing.md,对应的 JSON 契约定义在 fixtures/batch/extract_batch_uri_all_missing.json。

该夹具的输入是两个指向不存在路径的 URI:

[ {"kind": "uri", "uri": "/nonexistent/a.pdf"}, {"kind": "uri", "uri": "/nonexistent/b.txt"} ]

它同时给出了本次调用必须满足的三条断言(assertions):

断言期望值含义
not_error无错误整个extract_batch调用本身成功返回,不会因单个输入失败而抛出异常
summary.results0没有任何一条输入产出提取结果
summary.errors2两条输入各产生一条错误记录

这正是批量 API 与单文件 API 的核心差异:调用级成功与条目级失败是分离的。两个输入全部失败,但外层调用依然返回一个结构化的ExtractionResult,其中summary.errors == inputs.length。

Dart 侧完整代码逐行解读

以下代码就是该夹具在 Dart 语言绑定下的可运行形态,它演示了从 JSON 构造输入、调用批量接口、读取汇总计数的完整链路:

import 'dart:convert'; import 'dart:io'; import 'package:xberg/xberg.dart'; import 'package:xberg/src/xberg_bridge_generated/frb_generated.dart' show RustLib; Future<void> main() async { await RustLib.init(); try { final inputs = await Future.wait((jsonDecode(r'[{"kind":"uri","uri":"/nonexistent/a.pdf"},{"kind":"uri","uri":"/nonexistent/b.txt"}]') as List<dynamic>).map((element) => createExtractInputFromJson(json: jsonEncode(element)))); final result = await XbergBridge.extractBatch(inputs); stdout.writeln(result.summary.results); stdout.writeln(result.summary.errors); } finally { RustLib.dispose(); } }

逐行拆解:

  1. 导入依赖:package:xberg/xberg.dart提供XbergBridge、ExtractInput等公开 API;frb_generated.dart中的RustLib是 flutter_rust_bridge 生成的运行时入口,负责初始化与释放与 Rust 核心的通信通道。
  2. await RustLib.init():在使用任何 Xberg 能力之前必须先初始化桥接运行时;对应的RustLib.dispose()放在finally中,保证无论成功失败都会释放资源。
  3. 构造输入:这里没有直接用 Dart 的ExtractInput构造器,而是把一段 JSON 数组通过jsonDecode解析后,逐个用createExtractInputFromJson(json: jsonEncode(element))转成ExtractInput。这种"从 JSON 构造输入"的方式与 Rust 侧ExtractInput的 serde 反序列化一一对应,可以让前端代码与后端契约(fixture JSON)保持同构。每个输入元素的kind: "uri"表示这是一个路径/URL 输入,uri字段则给出具体位置。
  4. 调用批量接口:XbergBridge.extractBatch(inputs)对应 Dart 封装在 packages/dart/lib/src/xberg.dart 中定义的方法extractBatch(List<ExtractInput> inputs, {ExtractionConfig? config})——未传config时默认使用{}对应的 Rust 侧默认配置。
  5. 读取汇总:result.summary.results与result.summary.errors分别是成功结果数与错误条目数。本场景下输出两行:第一行0,第二行2。

引擎内部:失败条目如何被收集而不是抛错

Dart 绑定背后是 Rust 核心的统一公共 API。在 crates/xberg/src/core/extract/mod.rs 中,extract_batch把输入委托给进程级默认引擎:

pub async fn extract_batch(inputs: Vec<ExtractInput>, config: &ExtractionConfig) -> Result<ExtractionResult> { DEFAULT_ENGINE.extract_batch(inputs, config).await }

真正的实现位于 crates/xberg/src/engine/extract_impl.rs 的extract_batch(L217 起)。它的关键设计包括:

  • 先校验、再缓存:调用前先执行config.validate();随后计算批量内容的缓存键,若命中缓存且反序列化成功则直接返回缓存结果。
  • 仅"零错误"才写缓存:代码中只有当output.errors.is_empty()时才会把结果写入缓存(见 extract_impl.rs)。本场景errors == 2,因此不会污染缓存——有失败项的批量结果不会被误当成干净数据复用。
  • 两种执行路径:
    • 在启用tokio-runtime且非 wasm32 的目标上走extract_batch_concurrent(extract_impl.rs),通过tokio::task::JoinSet并发处理各输入;
    • 在 wasm32 或未启用tokio-runtime时退化为extract_batch_sequential(extract_impl.rs),逐个await。
    • 两条路径的失败处理策略完全一致:单项失败被捕获并追加进output.errors,不会中断整批循环。以顺序路径为例,循环体内Err(error) => output.errors.push(error_item(index, source, &error)),处理完所有输入后调用output.refresh_counts()重新统计计数。

"文件不存在"这类错误在底层表现为XbergError::Io,其io::ErrorKind为NotFound——这一点在 crates/xberg/src/core/extractor/file.rs 的测试should_report_missing_file_before_invalid_ocr_configuration中有明确印证:即使同时配置了 OCR,缺失文件也会优先以 NotFound 报告。

结果类型:summary 与 error 条目的字段契约

批量调用的返回类型定义在 crates/xberg/src/core/config/extraction/types.rs:

ExtractionSummary(types.rs)是result.summary的类型,包含六个计数:

字段类型含义本场景取值
inputsusize调用方提交的输入总数2
resultsusize成功产出的提取结果数0
errorsusize逐条错误数2
remote_urlsusize解析为远程 HTTP(S) URL 的 URI 数0
pages_crawledusize被抓取/爬取的 HTML 页数0
documents_downloadedusize从 URL 下载的非 HTML 文档数0

ExtractionResult(types.rs)除results、errors、summary外,还携带爬取过程信息(crawl_final_urls、crawl_redirect_count、crawl_unique_normalized_urls),便于审计 URL 跳转链路。

每条错误都是结构化的ExtractionErrorItem(types.rs):

字段类型含义
indexusize出错输入在原始请求中的下标
codeu32稳定的数字错误码
error_typeString稳定的 snake_case 错误类别
sourceString尽力而为的源标识(如 URI 原文)
messageString人类可读的错误信息

这意味着你不仅知道"失败了 2 条",还能通过errors[i].index精确还原是哪两条、通过source看到原始 URI、通过code/error_type做程序化分类。

输入模型:kind 与 uri 的约束

Dart 侧createExtractInputFromJson转换出的结构,对应 Rust 侧ExtractInput(types.rs)。其中ExtractInputKind(types.rs)只有两种取值:

  • bytes:内存中直接给出的原始字节,配套字段bytes;
  • uri:文件系统路径、file://URI 或 HTTP(S) URL,配套字段uri。

类型定义上"bytes要求bytes、uri要求uri",uri缺省时还会触发校验错误(见 crates/xberg/tests/core_integration.rs 的missing uri field should fail validation)。本场景两个输入都正确提供了kind: "uri"与uri,问题只在于路径指向的文件不存在,因此错误发生在提取阶段而非校验阶段。

与其他批量夹具的对照:判断"全部失败"的边界

同一目录下的系列夹具可以帮助你判断当前场景在整个批量错误矩阵中的位置(见 docs-site/src/snippets-generated/dart/batch):

  • extract_batch_uri_basic:全部 URI 存在,期望results == inputs、errors == 0;
  • extract_batch_uri_partial_failure:部分 URI 存在、部分缺失,期望results + errors == inputs;
  • extract_batch_empty_inputs:输入列表为空,summary.inputs == 0;
  • extract_batch_uri_all_missing(本文场景):全部URI 缺失,期望results == 0、errors == inputs,且调用本身不报错。

这些行为在 Rust 集成测试中同样被覆盖,例如 crates/xberg/tests/batch_processing.rs 的test_batch_extract_all_fail:三个不存在的文件(txt/pdf/docx)批量提取后,断言"批量调用整体成功,但每个结果的 metadata.error 均非空"。

实战要点:如何把"全失败"变成可运维的信号

结合上述类型契约,在真实项目中处理"全部缺失"场景时建议:

  1. 不要用 try/catch 判断单个文件失败。extract_batch的调用级错误只代表配置非法、取消或灾难性故障;文件缺失这种条目级错误永远出现在result.errors里。判断维度始终是summary.results、summary.errors与summary.inputs三者是否满足results + errors == inputs。
  2. 用errors[i].index与source回填原始输入。批量输入在客户端往往有业务序号(文件名、数据库 ID),而错误项只携带下标,因此保持输入列表顺序不变即可精确映射"哪条输入失败了、失败原因是什么"。
  3. 对code/error_type做程序化分类。不要靠解析message字符串判断错误类别,优先使用稳定的错误码与错误类型字段,例如把NotFound类错误与"超时""格式不支持"区分处理。
  4. 注意缓存语义。只有零错误的批量结果才会被写入提取缓存;包含失败项的批次每次都会重新执行。若你的批处理经常出现部分失败,可通过错误计数提前感知缓存未命中的开销。
  5. 配合单文件容错链路理解。批量内部的错误处理与extract_uri_document等单条路径共用同一套ExtractionErrorItem契约,因此你可以先在小样本上逐个验证单文件行为,再放大到批量场景。

小结

extract_batch面对"全部 URI 缺失"时的行为可以概括为一句话:调用级成功、条目级全失败、失败信息结构化。通过 extract_batch_uri_all_missing.md 这段 Dart 示例,配合 fixtures/batch/extract_batch_uri_all_missing.json 的断言、engine/extract_impl.rs 的实现以及 types.rs 的类型定义,你可以在自己的 Dart/Flutter 应用中可靠地实现"批量提取 + 逐条容错 + 精确审计",让异常输入不再中断整条流水线。

  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:16:39

真空共晶焊接空洞率偏高?青岛真空共晶机公司推荐排查思路

焊接面空洞率从3%跳到12%、瓦片TR组件垂直互联真空共晶焊接的互连柱出现裂纹、同一炉产品批次一致性忽好忽坏——这三类异常占了我这些年处理过的真空共晶问题的七成以上。多数时候设备没坏&#xff0c;问题出在真空度、升温曲线、冷却段这三个环节中的一个。先做空洞率分布测试…

作者头像 李华
网站建设 2026/9/28 20:16:19

我对等保2.0的理解

等保2.0即网络安全等级保护2.0&#xff0c;是《网络安全法》规定的基础性网络安全制度。它将系统划分为5个保护等级&#xff0c;核心框架为一个中心&#xff0c;三重防护&#xff0c;防护思路从静态被动转为动态主动的全生命周期防护。保护对象覆盖传统系统及云、大数据、物联网…

作者头像 李华
网站建设 2026/9/28 20:16:19

HTML——庞杂的表单控件元素(一)

庞杂的表单控件元素1、先从元素说起1.1、<form>元素的行为与特征1.1.1、submit事件与submit()方法1.1.2、requestSubmit()方法1.1.3、submitter属性1.1.4、formdata事件1.1.5、reset方法和事件1.1.6、method"dialog"1.1.7、表单元素的关联性1.2、并不简单的<…

作者头像 李华
网站建设 2026/9/28 20:14:50

国内高校学生常用的AI论文网站有哪些?

国内高校学生常用的 AI 论文工具&#xff0c;以本土化全流程产品为主&#xff0c;结合通用大模型与专业辅助功能&#xff0c;覆盖选题、框架搭建、初稿撰写、语言润色、降重处理、查重检测及格式排版等关键环节&#xff0c;以下是主流工具详解与对比&#xff1a;一、本土全流程…

作者头像 李华
网站建设 2026/9/28 20:14:34

CTF 流量分析实战:从 Wireshark 到 tshark 还原 HTTP 盲注流量中的 Flag

文档网络安全教程 【免费下载链接】ctf-wiki Come and join us, we need you! 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ct/ctf-wiki 点击查看 免费下载 导读 本篇技术指南以 CTF 中经典的流量包取证场景为主线&#xff0c;围绕 ctf-wiki 仓库中 HTTP 协议分析文…

作者头像 李华