This repository has been archived by the owner on Dec 1, 2021. It is now read-only.
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.
PROPOSAL: Add support for domain errors #130
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
Assignees
Labels
No labels
Activity