docs(bf-4482v): document extraction result error structure
- Analyzed ExtractionResult and ExtractionMetadata structure - Documented internal Diagnostic structure with code, offset, object_ref, message - Mapped DiagCode categories (STRUCT_*, STREAM_*, XREF_*, etc.) - Explained severity levels (Info, Warning, Error, Fatal) - Traced error flow from emission to string conversion - Identified key files: extract.rs, diagnostics.rs Closes bf-4482v
This commit is contained in:
parent
1379bc62e2
commit
6117735ed2
1 changed files with 164 additions and 0 deletions
164
notes/bf-4482v.md
Normal file
164
notes/bf-4482v.md
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
# Extraction Result Error Structure Analysis
|
||||
|
||||
## Overview
|
||||
This document analyzes how errors and diagnostics are organized in the pdftract extraction result structure.
|
||||
|
||||
## ExtractionResult Structure
|
||||
|
||||
The main `ExtractionResult` struct (defined in `crates/pdftract-core/src/extract.rs`) contains:
|
||||
|
||||
```rust
|
||||
pub struct ExtractionResult {
|
||||
pub fingerprint: String,
|
||||
pub pages: Vec<PageResult>,
|
||||
pub metadata: ExtractionMetadata,
|
||||
pub signatures: Vec<SignatureJson>,
|
||||
pub form_fields: Vec<FormFieldJson>,
|
||||
pub links: Vec<LinkJson>,
|
||||
pub attachments: Vec<AttachmentJson>,
|
||||
pub threads: Vec<ThreadJson>,
|
||||
pub javascript_actions: Vec<JavascriptActionJson>,
|
||||
}
|
||||
```
|
||||
|
||||
## Error Reporting Locations
|
||||
|
||||
### 1. Document-Level Diagnostics
|
||||
|
||||
**Location**: `ExtractionResult.metadata.diagnostics: Vec<String>`
|
||||
|
||||
**Purpose**: Contains warnings and errors that affect the entire extraction process.
|
||||
|
||||
**Examples**:
|
||||
- Tagged PDF detected (StructTree traversal deferred)
|
||||
- Xref repaired via forward scan
|
||||
- Coverage warnings
|
||||
- Page range errors
|
||||
|
||||
### 2. Per-Page Errors
|
||||
|
||||
**Location**: `PageResult.error: Option<String>`
|
||||
|
||||
**Purpose**: Contains error messages when extraction fails for a specific page.
|
||||
|
||||
**Structure**:
|
||||
```rust
|
||||
pub struct PageResult {
|
||||
pub index: usize,
|
||||
pub page_number: u32,
|
||||
pub page_label: Option<String>,
|
||||
pub width: Option<f32>,
|
||||
pub height: Option<f32>,
|
||||
pub rotation: Option<u16>,
|
||||
pub page_type: Option<String>,
|
||||
pub spans: Vec<SpanJson>,
|
||||
pub blocks: Vec<BlockJson>,
|
||||
pub tables: Vec<TableJson>,
|
||||
pub annotations: Vec<AnnotationJson>,
|
||||
pub error: Option<String>, // ← Per-page error
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Metadata Error Count
|
||||
|
||||
**Location**: `ExtractionMetadata.error_count: usize`
|
||||
|
||||
**Purpose**: Tracks the total number of pages that failed to extract.
|
||||
|
||||
## Internal Diagnostic Structure
|
||||
|
||||
Before being converted to strings, diagnostics use the rich `Diagnostic` structure:
|
||||
|
||||
```rust
|
||||
pub struct Diagnostic {
|
||||
pub code: DiagCode, // Error type code
|
||||
pub byte_offset: Option<u64>, // Location in file
|
||||
pub object_ref: Option<ObjRef>, // PDF object reference
|
||||
pub message: Cow<'static, str>, // Human-readable message
|
||||
}
|
||||
```
|
||||
|
||||
## Diagnostic Code Categories
|
||||
|
||||
The `DiagCode` enum categorizes errors with prefixes:
|
||||
|
||||
| Category | Prefix | Description |
|
||||
|----------|--------|-------------|
|
||||
| Structure | `STRUCT_*` | PDF structure errors (parser/object/document) |
|
||||
| Stream | `STREAM_*` | Stream decoder errors |
|
||||
| XREF | `XREF_*` | Cross-reference table errors |
|
||||
| Encryption | `ENCRYPTION_*` | Encryption-related errors |
|
||||
| Page | `PAGE_*` | Page-level errors |
|
||||
| Font | `FONT_*` | Font pipeline errors |
|
||||
| Graphics State | `GSTATE_*` | Graphics state errors |
|
||||
| Layout | `LAYOUT_*` | Layout and reading order errors |
|
||||
| OCR | `OCR_*` | OCR pipeline errors |
|
||||
| Remote | `REMOTE_*` | Remote source errors |
|
||||
| MCP | `MCP_*` | MCP server errors |
|
||||
| Cache | `CACHE_*` | Cache errors |
|
||||
| Security | `SECURITY_*` | Security-related diagnostics |
|
||||
|
||||
## Severity Levels
|
||||
|
||||
Diagnostics have four severity levels:
|
||||
|
||||
1. **Info** — Does not affect output validity
|
||||
- Examples: `XREF_REPAIRED`, `TAGGED_PDF_STRUCT_TREE_DEFERRED`
|
||||
|
||||
2. **Warning** — Output is usable but degraded
|
||||
- Examples: `STRUCT_INVALID_NAME`, `FONT_GLYPH_UNMAPPED`, `STREAM_DECODE_ERROR`
|
||||
|
||||
3. **Error** — Output for this region/page is invalid; other regions OK
|
||||
- Examples: `STREAM_BOMB`, `PAGE_OUT_OF_RANGE`, `REMOTE_FETCH_INTERRUPTED`
|
||||
|
||||
4. **Fatal** — Extraction aborted, no usable output
|
||||
- Examples: `ENCRYPTION_UNSUPPORTED`, `REMOTE_TLS_FAILED`, `REMOTE_DNS_FAILED`
|
||||
|
||||
## Error Flow
|
||||
|
||||
1. **Emission**: During extraction, `Diagnostic` structs are emitted via the `emit!()` macro
|
||||
2. **Collection**: Diagnostics are collected in `Vec<Diagnostic>`
|
||||
3. **Conversion**: Before returning `ExtractionResult`, diagnostics are converted to strings:
|
||||
```rust
|
||||
let diagnostics: Vec<String> = coverage_result
|
||||
.diagnostics
|
||||
.iter()
|
||||
.map(|d| d.message.as_ref().to_string())
|
||||
.collect();
|
||||
```
|
||||
4. **Exposure**: Final string messages are exposed in `ExtractionMetadata.diagnostics`
|
||||
|
||||
## Key Files
|
||||
|
||||
- `crates/pdftract-core/src/extract.rs` - Main extraction pipeline, defines `ExtractionResult`
|
||||
- `crates/pdftract-core/src/diagnostics.rs` - Diagnostic system, defines `Diagnostic` and `DiagCode`
|
||||
- `src/graphics_state/diagnostics.rs` - Legacy diagnostic types (graphics state only)
|
||||
|
||||
## Example Diagnostic
|
||||
|
||||
```rust
|
||||
// Creating a diagnostic
|
||||
Diagnostic::with_static(
|
||||
DiagCode::StreamDecodeError,
|
||||
12345, // byte offset
|
||||
"zlib stream truncated mid-inflation"
|
||||
)
|
||||
|
||||
// Converts to string in metadata:
|
||||
// "STREAM_DECODE_ERROR: zlib stream truncated mid-inflation (byte offset 12345)"
|
||||
```
|
||||
|
||||
## Acceptance Criteria Status
|
||||
|
||||
✅ **Error array structure understood**
|
||||
- Document-level diagnostics in `metadata.diagnostics`
|
||||
- Per-page errors in `PageResult.error`
|
||||
|
||||
✅ **Error fields documented**
|
||||
- Internal `Diagnostic` struct with code, offset, object_ref, message
|
||||
- Final string representation in extraction result
|
||||
|
||||
✅ **Relationship between errors and extraction phases clear**
|
||||
- Each diagnostic has a phase origin (e.g., "1.1", "1.5", "3.1")
|
||||
- DiagCode category prefixes indicate which layer emitted the error
|
||||
- Severity levels indicate impact on extraction result
|
||||
Loading…
Add table
Reference in a new issue