Vapor - Handling Database errors
What could go wrong when saving to a database you ask?
Well, lots of things, starting from issues with the data being saved to issues with database connections, locks, timeouts etc. Some can be dealt with amicably and some are better left untouched.
By default, vapor would throw these database errors as 500 response errors. From the Vapor docs:
"Throwing or returning a Swift Error will result in a 500 status response and the error will be logged. AbortError and DebuggableError can be used to change the resulting response and logging respectively"
But we can handle some database errors to display better error responses messages.
For instance, we can add some constaints to the schema, like unique to ensure we don't end up with duplicates or foreign key constraints to ensure referential integrity in our database tables when using Parent-Child or Sibling relationships.
But when we encounter such issues while trying to save data we could inform the end user of the exact issue with the data provided to the application so they may understand and correct the erroneous data if possible instead of throwing an incongruous 500 server error
Example:
item.save(on: database)
.map { item }
.flatMapError { error in
if let dbError = error as? DatabaseError, dbError.isConstraintFailure {
return req.db.eventLoop.makeFailedFuture(
Abort(.forbidden,
reason: "An item with that name already exists or the associated key referenced is incorrect"))
}
return req.db.eventLoop.makeFailedFuture(error)
}
References: Vapor Discord server