import Foundation enum GenerationError: Error { case missingMarkerInTemplate(String) case failedToLoadTemplate(String) case failedToWriteFile(String) case failedToOpenFile(String) case failedToDecodeJSON(file: String, error: String) case invalidLanguageSpecification(String) case invalidDateInPageMetadata(String) case failedToEncodeJSON(String) case missingSectionMetadata(section: String, language: String) case missingPageMetadata(page: String, language: String) case missingPage(page: String, language: String) case missingImage(String) case conflictingImageSources(output: String, in1: String, in2: String) case conflictingImageRatios(output: String, in1: String, in2: String) case failedToGenerateImage(String) case imageRatioMismatch(String) } func wrap(_ error: GenerationError, execute: () throws -> T) rethrows -> T { do { return try execute() } catch let underlyingError { print(underlyingError) throw error } } func wrap(_ error: (Error) -> GenerationError, execute: () throws -> T) rethrows -> T { do { return try execute() } catch let underlyingError { print(underlyingError) throw error(underlyingError) } } extension Optional { func unwrap(or error: GenerationError) throws -> Wrapped { switch self { case .none: throw error case .some(let wrapped): return wrapped } } }