Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Commit

Permalink
refactor(error-handling): enforce wrap check
Browse files Browse the repository at this point in the history
add error handling for external packages mainly magistrala SDK

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
  • Loading branch information
rodneyosodo committed Mar 14, 2024
1 parent 65b5b55 commit af2de20
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 175 deletions.
9 changes: 9 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ linters-settings:
unused:
field-writes-are-uses: false
generated-is-used: false
wrapcheck:
ignoreSigRegexps:
- "github.com/absmach/magistrala-ui/ui.Service"
- "encoding/json.*"
- "net/http.Request"
- "golang.org/x/sync/errgroup.Group"
- "net/http.ResponseWriter"


linters:
disable-all: true
Expand Down Expand Up @@ -78,3 +86,4 @@ linters:
- unconvert
- unparam
- usestdlibvars
- wrapcheck
15 changes: 8 additions & 7 deletions ui/api/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/absmach/magistrala-ui/ui"
"github.com/absmach/magistrala/pkg/errors"
"github.com/go-kit/kit/endpoint"
"github.com/golang-jwt/jwt"
"github.com/gorilla/securecookie"
Expand Down Expand Up @@ -284,11 +285,11 @@ func secureTokenEndpoint(svc ui.Service, s *securecookie.SecureCookie, prefix st

session, err := json.Marshal(sessionDetails)
if err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONMarshal, err)
}
secureSessionDetails, err := s.Encode(sessionDetailsKey, string(session))
if err != nil {
return nil, err
return nil, errors.Wrap(errCookieEncrypt, err)
}

return uiRes{
Expand Down Expand Up @@ -334,11 +335,11 @@ func refreshTokenEndpoint(svc ui.Service, s *securecookie.SecureCookie) endpoint
req.Session.Token = token
session, err := json.Marshal(req.Session)
if err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONMarshal, err)
}
secureSessionDetails, err := s.Encode(sessionDetailsKey, string(session))
if err != nil {
return nil, err
return nil, errors.Wrap(errCookieEncrypt, err)
}

tkr := uiRes{
Expand Down Expand Up @@ -1563,11 +1564,11 @@ func domainLoginEndpoint(svc ui.Service, s *securecookie.SecureCookie, prefix st
sessionDetails.Token = token
session, err := json.Marshal(sessionDetails)
if err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONMarshal, err)
}
secureSessionDetails, err := s.Encode(sessionDetailsKey, string(session))
if err != nil {
return nil, err
return nil, errors.Wrap(errCookieEncrypt, err)
}

return uiRes{
Expand Down Expand Up @@ -2034,7 +2035,7 @@ func deleteDashboardEndpoint(svc ui.Service) endpoint.Endpoint {
func extractTokenExpiry(token string) (time.Time, error) {
jwtToken, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
if err != nil {
return time.Time{}, err
return time.Time{}, errors.Wrap(errParseToken, err)
}
var expTime time.Time
if claims, ok := jwtToken.Claims.(jwt.MapClaims); ok {
Expand Down
3 changes: 3 additions & 0 deletions ui/api/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ var (
errMissingRefreshToken = errors.New("missing refresh token")
errMissingRef = errors.New("missing ref")
errInvalidQueryParams = errors.New("invalid query parameters")
errInvalidFormValue = errors.New("invalid form values")
errFileFormat = errors.New("invalid file format")
errInvalidFile = errors.New("unsupported file type")
errMissingDomainID = errors.New("missing domain id")
errMissingRole = errors.New("missing role")
errMissingValue = errors.New("missing value")
errCookieDecryption = errors.New("failed to decrypt the cookie")
errCookieEncrypt = errors.New("failed to encrypt the cookie")
errMissingFrom = errors.New("missing from time value")
errMissingTo = errors.New("missing to time value")
errInvalidAggregation = errors.New("invalid aggregation value")
errInvalidInterval = errors.New("invalid interval value")
errParseToken = errors.New("failed to parse token")
)
44 changes: 26 additions & 18 deletions ui/api/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -1093,11 +1093,11 @@ func decodeRefreshTokenRequest(s *securecookie.SecureCookie) kithttp.DecodeReque
}
var session string
if err := s.Decode(sessionDetailsKey, sessionCookie, &session); err != nil {
return nil, err
return nil, errors.Wrap(errCookieDecryption, err)
}
var sessionDetails ui.Session
if err := json.Unmarshal([]byte(session), &sessionDetails); err != nil {
return ui.Session{}, err
return ui.Session{}, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
referer, err := readStringQuery(r, refererKey, defKey)
if err != nil {
Expand Down Expand Up @@ -1144,11 +1144,11 @@ func decodeUserCreation(_ context.Context, r *http.Request) (interface{}, error)
}
var meta map[string]interface{}
if err := json.Unmarshal([]byte(r.PostFormValue("metadata")), &meta); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
var tags []string
if err := json.Unmarshal([]byte(r.PostFormValue("tags")), &tags); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
credentials := sdk.Credentials{
Identity: r.PostFormValue("identity"),
Expand Down Expand Up @@ -1386,11 +1386,11 @@ func decodeThingCreation(_ context.Context, r *http.Request) (interface{}, error
}
var meta map[string]interface{}
if err := json.Unmarshal([]byte(r.PostFormValue("metadata")), &meta); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
var tags []string
if err := json.Unmarshal([]byte(r.PostFormValue("tags")), &tags); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}

return createThingReq{
Expand Down Expand Up @@ -1548,7 +1548,7 @@ func decodeChannelCreation(_ context.Context, r *http.Request) (interface{}, err
}
var meta map[string]interface{}
if err := json.Unmarshal([]byte(r.PostFormValue("metadata")), &meta); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}

ch := sdk.Channel{
Expand Down Expand Up @@ -1723,7 +1723,7 @@ func decodeGroupCreation(_ context.Context, r *http.Request) (interface{}, error
}
var meta map[string]interface{}
if err := json.Unmarshal([]byte(r.PostFormValue("metadata")), &meta); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}

return createGroupReq{
Expand Down Expand Up @@ -1826,7 +1826,7 @@ func decodeGroupStatusUpdate(_ context.Context, r *http.Request) (interface{}, e
func decodePublishRequest(_ context.Context, r *http.Request) (interface{}, error) {
floatValue, err := strconv.ParseFloat(r.PostFormValue("value"), 64)
if err != nil {
return nil, err
return nil, errors.Wrap(errInvalidFormValue, err)
}

return publishReq{
Expand Down Expand Up @@ -2025,7 +2025,7 @@ func decodeUpdateBootstrapState(_ context.Context, r *http.Request) (interface{}
}
state, err := strconv.Atoi(r.FormValue("state"))
if err != nil {
return nil, err
return nil, errors.Wrap(errInvalidFormValue, err)
}

return updateBootstrapStateReq{
Expand Down Expand Up @@ -2488,7 +2488,7 @@ func readBoolQuery(r *http.Request, key string, def bool) (bool, error) {
func tokenFromCookie(r *http.Request, cookie string) (string, error) {
c, err := r.Cookie(cookie)
if err != nil {
return "", errors.Wrap(err, errInvalidCredentials)
return "", errors.Wrap(errInvalidCredentials, err)
}

return c.Value, nil
Expand All @@ -2498,7 +2498,7 @@ func sessionFromHeader(r *http.Request) (ui.Session, error) {
session := r.Header.Get(sessionDetailsKey)
var sessionDetails ui.Session
if err := json.Unmarshal([]byte(session), &sessionDetails); err != nil {
return ui.Session{}, err
return ui.Session{}, errors.Wrap(ui.ErrJSONUnmarshal, err)
}

return sessionDetails, nil
Expand Down Expand Up @@ -2590,8 +2590,7 @@ func DecryptCookieMiddleware(s *securecookie.SecureCookie, prefix string) func(h
return
}
if err = s.Decode(sessionDetailsKey, sessionCookie, &decryptedSessionCookie); err != nil {
err = errors.Wrap(err, errCookieDecryption)
http.Redirect(w, r, fmt.Sprintf("%s/%s?error=%s", prefix, errorAPIEndpoint, url.QueryEscape(err.Error())), http.StatusSeeOther)
http.Redirect(w, r, fmt.Sprintf("%s/%s?error=%s", prefix, errorAPIEndpoint, url.QueryEscape(errors.Wrap(errCookieDecryption, err).Error())), http.StatusSeeOther)
return
}

Expand All @@ -2605,7 +2604,7 @@ func DecryptCookieMiddleware(s *securecookie.SecureCookie, prefix string) func(h
func handleStaticFiles(m *chi.Mux) error {
entries, err := ui.StaticFS.ReadDir(ui.StaticDir)
if err != nil {
return err
return errors.Wrap(ui.ErrReadDir, err)
}
for _, entry := range entries {
if entry.IsDir() {
Expand All @@ -2630,7 +2629,7 @@ func parseMetadata(r *http.Request) (map[string]interface{}, error) {
metadata := make(map[string]interface{})
if len(metadataStr) > 0 {
if err := json.Unmarshal([]byte(metadataStr), &metadata); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
}

Expand All @@ -2643,7 +2642,7 @@ func parseTags(r *http.Request) ([]string, error) {
tags := make([]string, 0)
if len(tagsStr) > 0 {
if err := json.Unmarshal([]byte(tagsStr), &tags); err != nil {
return nil, err
return nil, errors.Wrap(ui.ErrJSONUnmarshal, err)
}
}

Expand Down Expand Up @@ -2698,6 +2697,7 @@ func encodeError(prefix string) kithttp.ErrorEncoder {
switch {
case errors.Contains(err, errInvalidCredentials),
errors.Contains(err, errAuthentication),
errors.Contains(err, errParseToken),
errors.Contains(err, ui.ErrTokenRefresh):
w.Header().Set("Location", fmt.Sprintf("%s/login", prefix))
w.WriteHeader(http.StatusSeeOther)
Expand All @@ -2709,7 +2709,10 @@ func encodeError(prefix string) kithttp.ErrorEncoder {
case errors.Contains(err, errInvalidFile):
w.Header().Set("X-Error-Message", err.Error())
w.WriteHeader(http.StatusUnsupportedMediaType)
case errors.Contains(err, errFileFormat):
case errors.Contains(err, errFileFormat),
errors.Contains(err, errCookieEncrypt),
errors.Contains(err, errInvalidQueryParams),
errors.Contains(err, errInvalidFormValue):
w.Header().Set("X-Error-Message", err.Error())
w.WriteHeader(http.StatusBadRequest)
case errors.Contains(err, ui.ErrFailedCreate),
Expand All @@ -2728,13 +2731,18 @@ func encodeError(prefix string) kithttp.ErrorEncoder {
errors.Contains(err, ui.ErrFailedResetRequest),
errors.Contains(err, ui.ErrFailedPublish),
errors.Contains(err, ui.ErrExecTemplate),
errors.Contains(err, ui.ErrParseTemplate),
errors.Contains(err, ui.ErrReadDir),
errors.Contains(err, ui.ErrFailedDelete),
errors.Contains(err, ui.ErrFailedShare),
errors.Contains(err, ui.ErrFailedUnshare),
errors.Contains(err, ui.ErrFailedDashboardSave),
errors.Contains(err, ui.ErrFailedDashboardDelete),
errors.Contains(err, ui.ErrFailedDashboardUpdate),
errors.Contains(err, ui.ErrJSONMarshal),
errors.Contains(err, ui.ErrJSONUnmarshal),
errors.Contains(err, ui.ErrFailedSend),
errors.Contains(err, ui.ErrFailedAccept),
errors.Contains(err, ui.ErrFailedDashboardRetrieve):
w.Header().Set("Location", fmt.Sprintf("%s/%s?error=%s", prefix, errorAPIEndpoint, url.QueryEscape(displayError.Error())))
w.WriteHeader(http.StatusSeeOther)
Expand Down
Loading

0 comments on commit af2de20

Please sign in to comment.