Reputation: 5912
I'm creating a static site generator in Swift, and am coming up with the API for adding "readers" - which are responsible for converting a raw file, of an extension they support, to a Page instance.
import Files
public struct Reader {
var supportedExtensions: [String]
var convert: (File) -> Page
}
public extension Reader {
static func markdownReader() throws -> Self {
Reader(supportedExtensions: ["md", "markdown"], convert: { file in
let contents = try file.readAsString(encodedAs: .utf8)
return Page(slug: "", title: "", content: contents, html: "")
})
}
}
The problem here is the I get the error Invalid conversion from throwing function of type '(File) throws -> Page' to non-throwing function type '(File) -> Page'
, which makes sense; nowhere in var convert: (File) -> Page
does it say it can throw, but the real problem is, that I can't add that either? So, how does one work with throwing closures, and store those closures as a property? Or can I simply not throw any errors in a closure?
Upvotes: 0
Views: 194
Reputation: 535231
Your throws
is in the wrong place:
static func markdownReader() throws -> Self {
markdownReader()
cannot throw. It just returns a Reader. The throwing, if any is going to happen, will happen in try file.readAsString
, which is inside the closure. The throw does not magically somehow filter up out of that closure definition to the place where it is defined!
So basically you have two choices. One is to declare that the closure type can in fact throw:
var convert: (File) throws -> Page
The other is: don't let the throw percolate up out of the closure. Catch it:
do {
let contents = try file.readAsString(encodedAs: .utf8)
return Page(slug: "", title: "", content: contents, html: "")
} catch {
// ???
}
The problem then is that in the catch
block you are still obligated to return a Page (unless you'd like to fatalError
at this point, on the grounds that the file can't be read so we may as well die). So you'd have to make up a page with fake content
, since you failed to obtain the contents from the File.
Upvotes: 3