- 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
164 lines
5.2 KiB
Markdown
164 lines
5.2 KiB
Markdown
# 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
|