Skip to main content

sqlite_graphrag/output/
human.rs

1//! Human-facing output on stderr, routed through `tracing`.
2//!
3//! Nothing here touches stdout. Keeping the two channels in separate modules
4//! is what makes "diagnostics on stderr, payload on stdout" checkable by
5//! reading a file name instead of auditing call sites.
6
7/// Logs `msg` as a structured `tracing::info!` event (does not write to stdout).
8/// v1.0.89: suppressed when stderr is not a terminal (pipe) to avoid
9/// polluting JSON pipelines when the user redirects stderr with `2>&1`.
10#[inline]
11pub fn emit_progress(msg: &str) {
12    if std::io::IsTerminal::is_terminal(&std::io::stderr()) {
13        tracing::info!(target: "output", message = msg);
14    }
15}
16
17/// Emits a bilingual progress message honouring `--lang` or XDG `i18n.lang`.
18/// v1.0.89: suppressed when stderr is not a terminal (pipe).
19pub fn emit_progress_i18n(en: &str, pt: &str) {
20    if !std::io::IsTerminal::is_terminal(&std::io::stderr()) {
21        return;
22    }
23    use crate::i18n::{current, Language};
24    match current() {
25        Language::English => tracing::info!(target: "output", message = en),
26        Language::Portuguese => tracing::info!(target: "output", message = pt),
27    }
28}
29
30/// Emits a localised error message to stderr via the `tracing` subscriber.
31///
32/// ADR-0047 / BUG-12 v1.0.88: prior implementation also called `eprintln!`
33/// which produced a SECOND stderr line (`Error:`/`Erro:` prefix) for the same
34/// error, on top of the structured `tracing::error!` line. Operators and
35/// log parsers observed duplicated stderr lines.
36///
37/// The tracing subscriber is configured for stderr at `main.rs:115`, so a
38/// single `tracing::error!` call already produces the human-readable line.
39/// Callers that want a plain stderr line without tracing (e.g. one-shot
40/// scripts) should use `eprintln!` directly instead of this helper.
41///
42/// Centralises human-readable error output following Pattern 5
43/// ([`crate::output`] is the SOLE I/O point of the CLI).
44#[cold]
45#[inline(never)]
46pub fn emit_error(localized_msg: &str) {
47    tracing::error!(target: "output", message = localized_msg);
48}
49
50/// Emits a bilingual error to stderr honouring `--lang` or XDG `i18n.lang`.
51/// Usage: `output::emit_error_i18n("invariant violated", "invariante violado")`.
52#[cold]
53#[inline(never)]
54pub fn emit_error_i18n(en: &str, pt: &str) {
55    use crate::i18n::{current, Language};
56    let msg = match current() {
57        Language::English => en,
58        Language::Portuguese => pt,
59    };
60    emit_error(msg);
61}