prisma-client-go
prisma-client-go copied to clipboard
Provide proper error handling
Apart from ErrNotFound, there are currently no other exported errors. We should export various errors such as unique constraint violations and so on. They should also contain details if possible.
For example, checking for a unique constraint violation could look as follows:
user, err := db.User.CreateOne(...)
if v, ok := prisma.IsUniqueConstraintViolation(err); ok {
// do something here
log.Printf("duplicate entry on columns %s", v.Fields)
} else if err != nil {
// probably nothing we can do here
return err
}
I am having similar problem and it's confusing...
This was working before:
func (r *mutationResolver) AddBranch(ctx context.Context, restaurantID int, data models.BranchInfo) (*db.RawBranch, error) {
query := r.DB.Restaurant.FindOne(db.Restaurant.ID.Equals(restaurantID))
restaurant, err := query.Exec(ctx)
if err != nil {
return nil, fmt.Errorf("cannot find restaurant of ID %d : %s", restaurantID, err.Error())
}
address, err := r.DB.Address.CreateOne(
db.Address.City.Set(data.Location.City),
db.Address.State.Set(data.Location.State),
db.Address.Landmark.Set(data.Location.Landmark),
db.Address.Street.Set(data.Location.Street),
db.Address.Lga.Set(data.Location.Lga),
).Exec(ctx)
if err != nil {
return nil, fmt.Errorf("cannot set branch address for restaurant of ID %d : %s", restaurantID, err.Error())
}
coord, err := r.DB.Coordinates.CreateOne(
db.Coordinates.Lat.Set(data.Location.Lat),
db.Coordinates.Lng.Set(data.Location.Lng),
).Exec(ctx)
if err != nil {
return nil, fmt.Errorf("cannot set coordinate for restaurant of ID %d : %s", restaurantID, err.Error())
}
location, err := r.DB.Location.CreateOne(
db.Location.Address.Link(db.Address.ID.Equals(address.ID)),
db.Location.Coordinates.Link(db.Coordinates.ID.Equals(coord.ID)),
).Exec(ctx)
if err != nil {
return nil, fmt.Errorf("cannot set branch location for restaurant %d : %s", restaurantID, err.Error())
}
branch, err := r.DB.Branch.CreateOne(
db.Branch.Name.Set(data.Name),
db.Branch.ContactEmail.Set(data.ContactEmail),
db.Branch.ContactPhone.Set(data.ContactPhone),
db.Branch.Location.Link(db.Location.ID.Equals(location.ID)),
db.Branch.Restaurant.Link(db.Restaurant.ID.Equals(restaurant.ID)),
).Exec(ctx)
if err != nil {
return nil, fmt.Errorf("could not register branch : %s", err.Error())
}
products := restaurant.Menu()
for _, product := range products {
r.DB.Branch.FindOne(db.Branch.ID.Equals(branch.ID)).Update(
db.Branch.Menu.Link(db.Product.ID.Equals(product.ID)),
).Exec(ctx)
}
return &branch.RawBranch, nil
}
mutation {
addBranch(restaurantId: 14, data:{
name:"Amuwo Branch",
contactEmail:"[email protected]",
contactPhone:"09024472756",
location: {
city: "Lagos",
state:"Lagos",
landmark:"Big Mosque",
street: "Apple Junction",
lga:"Amuwo Odofin",
lat: 6.471063,
lng: 3.312688
}
}){
id
}
}
Now I get this:
{
"errors": [
{
"message": "cannot find restaurant of ID 14 : ErrNotFound",
"path": [
"addBranch"
]
}
],
"data": null
}
@darmie Can you please open a new issue? Thanks!
@steebchen nevermind, it works now.. It seems the server that handles the DB transactions was not ready.
Returning detailed errors such as:
type UniqueConstraintViolation struct {
Message string
Fields []string
}
type (e UniqueConstraintViolation) Error() string {
return e.Message
}
is unfortunately not as simple as it sounds, since different databases return different information.
For example, a unique constraint violation error in Postgres returns the fields, while MySQL returns the violated index name.
We could introduce errors depending on database provider, such as PostgresUniqueConstraintViolation
and so on to solve this problem.
depends on https://github.com/prisma/prisma/issues/5040
Implementation via #1069. Please comment on the PR for any feedback. For other kinds of errors, please open a new issue.