I'm using Vapor 3 and linking to a FoundationDB database, so Im not using Fluent. I have a method that searches for a record, but it will obviously crash if it does not return a record (because I force unwrap the value).
I want to guard the reading from the database and return a response if no record is found. This will however not be the record as was expected in the Future. I was thinking that I should return a different response, but am unsure how to change the result that is expected.
//creates a specific country
func getCountry( req: Request) throws -> Future<Country> {
// get Country name from get parameter string
let countryString = try req.parameters.next(String.self)
// get record from Database. This could fail and so needs to be guarded. What response should be returned as the Future requires a Country datatype?
let record = FDBConnector().getRecord(path: Subspace("iVendor").subspace(["Countries", countryString]))
let newCountry = try JSONDecoder().decode(Country.self, from: record!)
// return Country Struct
return Future.map(on: req) {return newCountry }
}
There are a couple of options here.
First, if you throw an error from the method:
guard let record = FDBConnector().getRecord(path: Subspace("iVendor").subspace(["Countries", countryString])) else {
throw Abort(.notFound, reason: "No country found with name \(countryString)")
}
The error will get converted to a 404 (Not Found) response with "No country found with name \(countryString)"
as the error message.
If you want more control over the resulting response, you can change the route hander's return type to Future<Response>
. You can then encode the Country
object to the response or create a custom error response. This method does take some extra work though.
let response = Response(using: req)
guard let record = FDBConnector().getRecord(path: Subspace("iVendor").subspace(["Countries", countryString])) else {
try response.content.encode(["message": "Country not found"])
response.http.status = .notFound
return response
}
try response.content.encode(record)
return response
Note that you will have to conform Country
to Content
if you want that snippet to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With