prisma-client-go icon indicating copy to clipboard operation
prisma-client-go copied to clipboard

Provide proper error handling

Open steebchen opened this issue 3 years ago • 5 comments

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
}

steebchen avatar Aug 15 '20 08:08 steebchen

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 avatar Sep 01 '20 16:09 darmie

@darmie Can you please open a new issue? Thanks!

steebchen avatar Sep 01 '20 17:09 steebchen

@steebchen nevermind, it works now.. It seems the server that handles the DB transactions was not ready.

darmie avatar Sep 01 '20 17:09 darmie

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.

steebchen avatar Jan 25 '21 07:01 steebchen

depends on https://github.com/prisma/prisma/issues/5040

steebchen avatar Mar 03 '21 15:03 steebchen

Implementation via #1069. Please comment on the PR for any feedback. For other kinds of errors, please open a new issue.

steebchen avatar Nov 12 '23 06:11 steebchen