Bead pdftract-5lvpu implements the Swift SDK for pdftract as a subprocess-based SDK using Foundation's Process with async/await. Targets macOS 13+ and Linux only; explicitly excludes iOS due to Apple's subprocess restrictions. Acceptance criteria status: - PASS: SPM package structure (Package.swift configured) - PASS: All 9 contract methods exposed in Methods.swift - PASS: All 8 error cases defined in Error.swift - PASS: iOS documented as unsupported in README.md - PASS: CI workflow configured (pdftract-swift-publish.yaml) - PASS: AsyncThrowingStream cancellation implemented - PASS: All model types complete (14 model files) - PASS: All options types complete (ExtractionOptions, TextOptions, etc.) - PASS: Conformance test suite defined (ConformanceTests.swift) - PASS: Cross-platform Process support (ProcessRunner actor) Files updated: - swift-sdk/README.md: Fixed GitHub URL from placeholder to jedarden/pdftract-swift Verification note: notes/pdftract-5lvpu.md References: - Plan: SDK Architecture / The Ten SDKs, line 3480 - Plan: SDK Architecture / Per-SDK Release Channels, line 3577 - Plan: SDK Acceptance Criteria, lines 3581-3589 - ADR-009: Argo Workflows on iad-ci only
115 lines
3.2 KiB
Swift
115 lines
3.2 KiB
Swift
//
|
|
// Error.swift
|
|
// Pdftract
|
|
//
|
|
// Error types for pdftract operations.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// Pdftract error types.
|
|
public enum PdftractError: Error, Equatable {
|
|
/// Invalid PDF file format.
|
|
case invalidPdf(String)
|
|
|
|
/// I/O error reading or writing files.
|
|
case ioError(String)
|
|
|
|
/// Network error when fetching from URL.
|
|
case networkError(String)
|
|
|
|
/// Memory allocation failure.
|
|
case outOfMemory
|
|
|
|
/// Parse error in PDF structure.
|
|
case parseError(String)
|
|
|
|
/// OCR processing error.
|
|
case ocrError(String)
|
|
|
|
/// Rendering error when generating page images.
|
|
case renderingError(String)
|
|
|
|
/// Generic internal error.
|
|
case internalError(String)
|
|
|
|
/// User-friendly error description.
|
|
public var localizedDescription: String {
|
|
switch self {
|
|
case .invalidPdf(let message):
|
|
return "Invalid PDF: \(message)"
|
|
case .ioError(let message):
|
|
return "I/O error: \(message)"
|
|
case .networkError(let message):
|
|
return "Network error: \(message)"
|
|
case .outOfMemory:
|
|
return "Out of memory"
|
|
case .parseError(let message):
|
|
return "Parse error: \(message)"
|
|
case .ocrError(let message):
|
|
return "OCR error: \(message)"
|
|
case .renderingError(let message):
|
|
return "Rendering error: \(message)"
|
|
case .internalError(let message):
|
|
return "Internal error: \(message)"
|
|
}
|
|
}
|
|
|
|
/// Error code for programmatic handling.
|
|
public var code: String {
|
|
switch self {
|
|
case .invalidPdf:
|
|
return "INVALID_PDF"
|
|
case .ioError:
|
|
return "IO_ERROR"
|
|
case .networkError:
|
|
return "NETWORK_ERROR"
|
|
case .outOfMemory:
|
|
return "OUT_OF_MEMORY"
|
|
case .parseError:
|
|
return "PARSE_ERROR"
|
|
case .ocrError:
|
|
return "OCR_ERROR"
|
|
case .renderingError:
|
|
return "RENDERING_ERROR"
|
|
case .internalError:
|
|
return "INTERNAL_ERROR"
|
|
}
|
|
}
|
|
|
|
/// Equatable conformance
|
|
public static func == (lhs: PdftractError, rhs: PdftractError) -> Bool {
|
|
switch (lhs, rhs) {
|
|
case (.invalidPdf(let a), .invalidPdf(let b)),
|
|
(.ioError(let a), .ioError(let b)),
|
|
(.networkError(let a), .networkError(let b)),
|
|
(.parseError(let a), .parseError(let b)),
|
|
(.ocrError(let a), .ocrError(let b)),
|
|
(.renderingError(let a), .renderingError(let b)),
|
|
(.internalError(let a), .internalError(let b)):
|
|
return a == b
|
|
case (.outOfMemory, .outOfMemory):
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Custom error type for JSON decoding failures with context.
|
|
public struct DecodingErrorWrapper: Error {
|
|
/// The underlying decoding error.
|
|
public let underlyingError: Error
|
|
|
|
/// Context about what was being decoded.
|
|
public let context: String
|
|
|
|
public init(underlyingError: Error, context: String) {
|
|
self.underlyingError = underlyingError
|
|
self.context = context
|
|
}
|
|
|
|
public var localizedDescription: String {
|
|
return "Failed to decode \(context): \(underlyingError.localizedDescription)"
|
|
}
|
|
}
|