This repository was archived by the owner on Dec 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 716
This repository was archived by the owner on Dec 1, 2021. It is now read-only.
PROPOSAL: Add support for domain errors #130
Copy link
Copy link
Open
Description
As of now, when wrapping an error we keep the cause of the error meaning that if we want to handle the error in a upper layer we need to know details about the lower layers. For example:
package users
var ErrUserDoesNotExist = errors.New("user does not exist")
type Repository interface {
GetUserById(id string) (*users.User, error)
}package mysql
type mysqlRepository struct {
ds datastore
}
func (mr *mysqlRepository) GetUserById (id string) (*users.User, error) {
record, err := ds.exec(fmt.Sprintf("SELECT * FROM `users` WHERE id = %s", id))
if err != nil {
return nil, errors.Wrap(err, "could not retrieve user from persistence")
// another option is to return ErrUserDoesNotExist
}
}Meaning that if I want to deal with the error, the handler should do something like:
package handlers
func (h *handler) UserProfile (c web.C, w http.ResponseWriter, r *http.Request) {
uid := c.URLParams["uid"]
u, err := h.userRepository.GetUserById(uid)Option 1:
The handler should now about the implementation details of the database.
if err.Cause() == mysql.NoRecordsFound {
w.WriteHeader(http.StatusNotFound)
}Option 2:
We do a string comparation
if err.Error() == "could not retrieve user from persistence"{
w.WriteHeader(http.StatusNotFound)
}IMO this could be solved with another function:
func Map(causeErr error, meaningErr error) error {
if causeErr == nil {
return nil
}
err := &withDecoration{
cause: causeErr,
meaning: meaningErr,
}
return &withStack{
err,
callers(),
}
}Option 3:
We do a string comparation
if err.Meaning() == ErrUserDoesNotExist {
w.WriteHeader(http.StatusNotFound)
}I could open a PR for this.
Metadata
Metadata
Assignees
Labels
No labels