エラー処理
エントリポイント analyze は Result<FuncSpace, MetricsError> を返します。このページでは、各バリアントの意味と、それぞれへの対処方法を説明します。
MetricsErroris#[non_exhaustive], so always include a_arm when matching to stay forward-compatible with future variants.
エラーバリアントのパターンマッチ
use big_code_analysis::{analyze, LANG, MetricsError, MetricsOptions, Source};
fn main() {
let result = analyze(
Source::new(LANG::Rust, b"this is not rust")
.with_name(Some("snippet.rs".to_owned())),
MetricsOptions::default(),
);
match result {
Ok(space) => println!("ok: {} lines", space.metrics.loc.sloc()),
Err(MetricsError::EmptyRoot) => {
eprintln!("walker produced no top-level FuncSpace");
}
Err(MetricsError::LanguageDisabled(lang)) => {
eprintln!("language {:?} is not enabled in this build", lang);
}
// `MetricsError` は `#[non_exhaustive]` です。新しいバリアントが追加される可能性があります。
Err(_) => eprintln!("unexpected MetricsError variant"),
}
}
各バリアントの意味
EmptyRoot: reserved; not produced today. The metric walker always pushes a synthetic top-levelUnitFuncSpacebefore walking the AST, so every parse (including empty, whitespace-only, and comment-only input) returnsOk(FuncSpace { kind: Unit, .. }). The variant is kept for a future walker change that could let the state stack legitimately drain to empty.LanguageDisabled(LANG): the requestedLANGis not enabled in this build. Every dispatch entry point produces it when the caller selects aLANGwhose per-language Cargo feature is off. The default feature set (all-languages) compiles every grammar in, so you only see this variant after opting into a narrower set (--no-default-features --features rust,…).
MetricsError has no ParseHasErrors or NonUtf8Path variant. Since it stays #[non_exhaustive], a future strict-parsing or strict-identifier mode can introduce them without a breaking change. Non-UTF-8 paths are already handled up front: the recommended analyze entry point takes a caller-supplied Source::name (Option<String>), so a lossy path is never round-tripped in the first place. The file-backed Ast::from_path is the one entry point that reads a path itself, and it returns its own #[non_exhaustive] FromPathError (Io, NonUtf8Path, Skipped(SkipReason), UnknownLanguage, Parse(MetricsError)) rather than widening MetricsError. Skipped carries the same SkipReason the bca walker prints when it skips an empty, tiny, UTF-16 or non-UTF-8 file, so a caller can say which gate declined the file; it supersedes the deprecated Unreadable.
tree-sitter は常に「ノー」と言うわけではない
Most parse errors do not surface as Err(_). Tree-sitter is an error-recovering parser: it produces a tree even for syntactically broken input, marking the bad regions with ERROR nodes. The metric walk computes numbers over the recovered tree. That means:
- Garbage in, numbers out. Feeding C++ source to
LANG::Pythongenerally produces anOk(FuncSpace)whose metrics are nonsense. Select the right language (viaguess_language, for example) before trusting the result. - Partial files score. A truncated file with an unterminated brace still returns
Ok(FuncSpace). The metrics reflect the recovered tree, not the intended source.
入力が正常にパースされたかどうかを知る必要がある場合は、tree-sitter の AST を自分で走査して ERROR ノードを数えるか(STABILITY.md の Node エスケープハッチを参照)、CLI 側で bca find -t ERROR を使ってください(Nodes ページを参照)。
? による MetricsError の伝播
MetricsError は [std::error::Error] を実装しているため、ボイラープレートなしに任意の Result<_, Box<dyn Error>> チェーンを通して伝播させられます。
#![allow(unused)]
fn main() {
use std::error::Error;
use big_code_analysis::{analyze, FuncSpace, LANG, MetricsOptions, Source};
pub fn run(
lang: LANG,
source: &[u8],
name: Option<String>,
) -> Result<FuncSpace, Box<dyn Error>> {
Ok(analyze(
Source::new(lang, source).with_name(name),
MetricsOptions::default(),
)?)
}
}
If you want a project-specific error type, an explicit From impl keeps call sites clean while letting you attach extra context (file path, language guess, and so on).
警告はエラーではない
The library writes warnings to stderr for non-fatal issues (malformed bca: suppression markers, and a ConcurrentRunner input path that is not a regular file). They do not abort the walk and they do not flip Ok to Err. If you run embedded inside a server or library and need to capture those warnings, redirect stderr at the process level; the library does not expose a programmatic warning sink.