I have a vapor (4) server and recently added a function to query the database for a resident using an email address:
func getResidentByEmail(req: Request) throws -> EventLoopFuture<Resident> {
let token = try req.auth.require(Token.self)
let email = req.parameters.get("email") ?? ""
return Resident.query(on: req.db)
.filter(\.$email == email)
.first()
.map { resident in
guard let resident else { return Resident() }
return resident
}
}
Initially this function worked: I was able to return a resident with an email address. Now my server crashes with this error:
FluentKit/Field.swift:23: Fatal error: Cannot access field before it is initialized or fetched: address
I don't understand where I'm accessing the address field before it's initialized. If I restart the server this might say phoneNumber instead of address or some other field, but the rest of the error stays the same.
Here's my Resident model:
final class Resident: Model, Content {
init() {
}
static let schema: String = "residents"
@ID(key: .id)
var id: UUID?
@Field(key: "firstName")
var firstName: String
@Field(key: "middleName")
var middleName: String
@Field(key: "lastName")
var lastName: String
@Field(key: "phoneNumber")
var phoneNumber: String
@Field(key: "email")
var email: String
@Field(key: "dob")
var dob: String
@Field(key: "address")
var address: String
@Field(key: "rentAmount")
var rentAmount: Double
@Field(key: "pastDueRentOwed")
var pastDueRentOwed: Double
@Field(key: "isPastDue")
var isPastDue: Bool
@Field(key: "isRetiredClient")
var isRetiredClient: Bool
@Field(key: "monthlyReminderScheduled")
var monthlyReminderScheduled: Bool
@Field(key: "house")
var house: String
@Field(key: "roomNumber")
var roomNumber: Int
@Field(key: "bedNumber")
var bedNumber: Int
@Field(key: "housePin")
var housePin: Int
@Field(key: "moveInDate")
var moveInDate: String
Instead of returning a new Resident instance with an empty initializer when no resident is found, handle the absence of a resident more appropriately. Try this
func getResidentByEmail(req: Request) throws -> EventLoopFuture<Resident> {
let token = try req.auth.require(Token.self)
let email = req.parameters.get("email") ?? ""
return Resident.query(on: req.db)
.filter(\.$email == email)
.first()
.unwrap(or: Abort(.notFound, reason: "Resident with email \(email) not found"))
}