SMQ-1744 - Error handling with TypedError created on top existing Error (#3170)

Signed-off-by: Arvindh <arvindh91@gmail.com>
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
Co-authored-by: Felix Gateru <felix.gateru@gmail.com>
This commit is contained in:
Arvindh
2025-12-22 13:01:52 +05:30
committed by GitHub
parent 1355bc8bb7
commit 3fcf2e5369
71 changed files with 1919 additions and 1623 deletions
+37 -137
View File
@@ -16,7 +16,6 @@ import (
"github.com/absmach/supermq/clients"
"github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/errors"
svcerr "github.com/absmach/supermq/pkg/errors/service"
"github.com/absmach/supermq/users"
"github.com/gofrs/uuid/v5"
)
@@ -184,146 +183,47 @@ func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
return
}
var wrapper error
if errors.Contains(err, apiutil.ErrValidation) {
wrapper, err = errors.Unwrap(err)
}
switch {
case errors.Contains(err, errors.ErrTryAgain):
w.WriteHeader(http.StatusUnprocessableEntity)
case errors.Contains(err, errors.ErrEmailAlreadyExists),
errors.Contains(err, errors.ErrUsernameNotAvailable),
errors.Contains(err, errors.ErrRouteNotAvailable),
errors.Contains(err, errors.ErrChannelRouteNotAvailable),
errors.Contains(err, errors.ErrDomainRouteNotAvailable),
errors.Contains(err, svcerr.ErrExternalAuthProviderCouldNotUpdate):
switch retErr := err.(type) {
case *errors.RequestError:
w.WriteHeader(http.StatusBadRequest)
case errors.Contains(err, svcerr.ErrAuthorization),
errors.Contains(err, svcerr.ErrDomainAuthorization),
errors.Contains(err, svcerr.ErrUnauthorizedPAT),
errors.Contains(err, svcerr.ErrSuperAdminAction):
err = unwrap(err)
w.WriteHeader(http.StatusForbidden)
case errors.Contains(err, svcerr.ErrAuthentication),
errors.Contains(err, apiutil.ErrBearerToken),
errors.Contains(err, svcerr.ErrLogin),
errors.Contains(err, apiutil.ErrUnsupportedTokenType):
err = unwrap(err)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.AuthNError:
w.WriteHeader(http.StatusUnauthorized)
case errors.Contains(err, svcerr.ErrMalformedEntity),
errors.Contains(err, apiutil.ErrMalformedPolicy),
errors.Contains(err, apiutil.ErrMissingSecret),
errors.Contains(err, errors.ErrMalformedEntity),
errors.Contains(err, apiutil.ErrMissingID),
errors.Contains(err, apiutil.ErrInvalidVerification),
errors.Contains(err, apiutil.ErrMissingName),
errors.Contains(err, apiutil.ErrMissingEmail),
errors.Contains(err, apiutil.ErrInvalidEmail),
errors.Contains(err, apiutil.ErrMissingHost),
errors.Contains(err, apiutil.ErrInvalidResetPass),
errors.Contains(err, apiutil.ErrEmptyList),
errors.Contains(err, apiutil.ErrMissingMemberKind),
errors.Contains(err, apiutil.ErrMissingMemberType),
errors.Contains(err, apiutil.ErrLimitSize),
errors.Contains(err, apiutil.ErrBearerKey),
errors.Contains(err, svcerr.ErrInvalidStatus),
errors.Contains(err, apiutil.ErrNameSize),
errors.Contains(err, apiutil.ErrInvalidIDFormat),
errors.Contains(err, apiutil.ErrInvalidQueryParams),
errors.Contains(err, apiutil.ErrMissingRelation),
errors.Contains(err, apiutil.ErrValidation),
errors.Contains(err, apiutil.ErrMissingPass),
errors.Contains(err, apiutil.ErrMissingConfPass),
errors.Contains(err, apiutil.ErrPasswordFormat),
errors.Contains(err, svcerr.ErrInvalidRole),
errors.Contains(err, svcerr.ErrInvalidPolicy),
errors.Contains(err, apiutil.ErrInvitationState),
errors.Contains(err, apiutil.ErrInvalidAPIKey),
errors.Contains(err, svcerr.ErrViewEntity),
errors.Contains(err, apiutil.ErrMissingCertData),
errors.Contains(err, apiutil.ErrInvalidContact),
errors.Contains(err, apiutil.ErrInvalidTopic),
errors.Contains(err, apiutil.ErrInvalidCertData),
errors.Contains(err, apiutil.ErrEmptyMessage),
errors.Contains(err, apiutil.ErrInvalidLevel),
errors.Contains(err, apiutil.ErrInvalidDirection),
errors.Contains(err, apiutil.ErrInvalidEntityType),
errors.Contains(err, apiutil.ErrMissingEntityType),
errors.Contains(err, apiutil.ErrInvalidTimeFormat),
errors.Contains(err, svcerr.ErrSearch),
errors.Contains(err, apiutil.ErrEmptySearchQuery),
errors.Contains(err, apiutil.ErrLenSearchQuery),
errors.Contains(err, apiutil.ErrMissingDomainID),
errors.Contains(err, apiutil.ErrMissingUserID),
errors.Contains(err, apiutil.ErrMissingPATID),
errors.Contains(err, apiutil.ErrMissingUsername),
errors.Contains(err, apiutil.ErrMissingUsernameEmail),
errors.Contains(err, apiutil.ErrMissingFirstName),
errors.Contains(err, apiutil.ErrMissingLastName),
errors.Contains(err, apiutil.ErrInvalidUsername),
errors.Contains(err, apiutil.ErrMissingIdentity),
errors.Contains(err, apiutil.ErrInvalidProfilePictureURL),
errors.Contains(err, apiutil.ErrSelfParentingNotAllowed),
errors.Contains(err, apiutil.ErrMissingChildrenGroupIDs),
errors.Contains(err, apiutil.ErrMissingParentGroupID),
errors.Contains(err, apiutil.ErrMissingConnectionType),
errors.Contains(err, apiutil.ErrMissingRoleName),
errors.Contains(err, apiutil.ErrMissingRoleID),
errors.Contains(err, apiutil.ErrMissingPolicyEntityType),
errors.Contains(err, apiutil.ErrMissingRoleMembers),
errors.Contains(err, apiutil.ErrMissingDescription),
errors.Contains(err, apiutil.ErrMissingEntityID),
errors.Contains(err, apiutil.ErrInvalidRouteFormat),
errors.Contains(err, svcerr.ErrRetainOneMember),
errors.Contains(err, apiutil.ErrMissingRoute):
err = unwrap(err)
w.WriteHeader(http.StatusBadRequest)
case errors.Contains(err, svcerr.ErrCreateEntity),
errors.Contains(err, svcerr.ErrUpdateEntity),
errors.Contains(err, svcerr.ErrRemoveEntity),
errors.Contains(err, svcerr.ErrEnableClient),
errors.Contains(err, svcerr.ErrEnableUser),
errors.Contains(err, svcerr.ErrDisableUser):
err = unwrap(err)
w.WriteHeader(http.StatusUnprocessableEntity)
case errors.Contains(err, svcerr.ErrNotFound):
err = unwrap(err)
w.WriteHeader(http.StatusNotFound)
case errors.Contains(err, errors.ErrStatusAlreadyAssigned),
errors.Contains(err, svcerr.ErrInvitationAlreadyRejected),
errors.Contains(err, svcerr.ErrInvitationAlreadyAccepted),
errors.Contains(err, svcerr.ErrConflict):
err = unwrap(err)
w.WriteHeader(http.StatusConflict)
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
err = unwrap(err)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.AuthZError:
w.WriteHeader(http.StatusForbidden)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.MediaTypeError:
w.WriteHeader(http.StatusUnsupportedMediaType)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.ServiceError:
w.WriteHeader(http.StatusUnprocessableEntity)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.NotFoundError:
w.WriteHeader(http.StatusNotFound)
if err := json.NewEncoder(w).Encode(retErr); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
return
case *errors.InternalError:
w.WriteHeader(http.StatusInternalServerError)
return
default:
w.WriteHeader(http.StatusInternalServerError)
}
if wrapper != nil {
err = errors.Wrap(wrapper, err)
}
if errorVal, ok := err.(errors.Error); ok {
if err := json.NewEncoder(w).Encode(errorVal); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
}
func unwrap(err error) error {
wrapper, err := errors.Unwrap(err)
if wrapper != nil {
return wrapper
}
return err
}
+75 -92
View File
@@ -218,121 +218,104 @@ func TestEncodeResponse(t *testing.T) {
func TestEncodeError(t *testing.T) {
cases := []struct {
desc string
errs []error
code int
desc string
err error
code int
hasBody bool
checkError bool
}{
{
desc: "BadRequest",
errs: []error{
apiutil.ErrMissingSecret,
svcerr.ErrMalformedEntity,
errors.ErrMalformedEntity,
apiutil.ErrMissingID,
apiutil.ErrEmptyList,
apiutil.ErrMissingMemberType,
apiutil.ErrMissingMemberKind,
apiutil.ErrLimitSize,
apiutil.ErrNameSize,
svcerr.ErrViewEntity,
},
code: http.StatusBadRequest,
desc: "RequestError - Missing Secret",
err: apiutil.ErrMissingSecret,
code: http.StatusBadRequest,
hasBody: true,
},
{
desc: "BadRequest with validation error",
errs: []error{
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingSecret),
errors.Wrap(apiutil.ErrValidation, svcerr.ErrMalformedEntity),
errors.Wrap(apiutil.ErrValidation, errors.ErrMalformedEntity),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingID),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrEmptyList),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingMemberType),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingMemberKind),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrLimitSize),
errors.Wrap(apiutil.ErrValidation, apiutil.ErrNameSize),
},
code: http.StatusBadRequest,
desc: "RequestError - Missing ID",
err: apiutil.ErrMissingID,
code: http.StatusBadRequest,
hasBody: true,
},
{
desc: "Unauthorized",
errs: []error{
svcerr.ErrAuthentication,
svcerr.ErrAuthentication,
apiutil.ErrBearerToken,
},
code: http.StatusUnauthorized,
},
{
desc: "NotFound",
errs: []error{
svcerr.ErrNotFound,
},
code: http.StatusNotFound,
desc: "RequestError - Empty List",
err: apiutil.ErrEmptyList,
code: http.StatusBadRequest,
hasBody: true,
},
{
desc: "Conflict",
errs: []error{
svcerr.ErrConflict,
svcerr.ErrConflict,
},
code: http.StatusConflict,
desc: "RequestError - Conflict",
err: svcerr.ErrConflict,
code: http.StatusBadRequest,
hasBody: true,
},
{
desc: "Forbidden",
errs: []error{
svcerr.ErrAuthorization,
svcerr.ErrAuthorization,
svcerr.ErrDomainAuthorization,
},
code: http.StatusForbidden,
desc: "NotFoundError - Not Found",
err: svcerr.ErrNotFound,
code: http.StatusNotFound,
hasBody: true,
},
{
desc: "UnsupportedMediaType",
errs: []error{
apiutil.ErrUnsupportedContentType,
},
code: http.StatusUnsupportedMediaType,
desc: "AuthNError - Authentication Failed",
err: svcerr.ErrAuthentication,
code: http.StatusUnauthorized,
hasBody: true,
},
{
desc: "StatusUnprocessableEntity",
errs: []error{
svcerr.ErrCreateEntity,
svcerr.ErrUpdateEntity,
svcerr.ErrRemoveEntity,
},
code: http.StatusUnprocessableEntity,
desc: "AuthZError - Authorization Failed",
err: svcerr.ErrAuthorization,
code: http.StatusForbidden,
hasBody: true,
},
{
desc: "InternalServerError",
errs: []error{
errors.New("test"),
},
code: http.StatusInternalServerError,
desc: "AuthZError - Domain Authorization Failed",
err: svcerr.ErrDomainAuthorization,
code: http.StatusForbidden,
hasBody: true,
},
{
desc: "MediaTypeError - Unsupported Content Type",
err: apiutil.ErrUnsupportedContentType,
code: http.StatusUnsupportedMediaType,
hasBody: true,
},
{
desc: "ServiceError - Create Entity Failed",
err: svcerr.ErrCreateEntity,
code: http.StatusUnprocessableEntity,
hasBody: true,
},
{
desc: "ServiceError - Update Entity Failed",
err: svcerr.ErrUpdateEntity,
code: http.StatusUnprocessableEntity,
hasBody: true,
},
{
desc: "ServiceError - Remove Entity Failed",
err: svcerr.ErrRemoveEntity,
code: http.StatusUnprocessableEntity,
hasBody: true,
},
{
desc: "InternalError",
err: errors.NewInternalError(),
code: http.StatusInternalServerError,
hasBody: false,
},
}
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
responseWriter := newResponseWriter()
for _, err := range c.errs {
api.EncodeError(context.Background(), err, responseWriter)
assert.Equal(t, c.code, responseWriter.StatusCode())
message := body{}
jerr := json.Unmarshal(responseWriter.Body(), &message)
assert.NoError(t, jerr)
var wrapper error
switch errors.Contains(err, apiutil.ErrValidation) {
case true:
wrapper, err = errors.Unwrap(err)
assert.Equal(t, err.Error(), message.Error)
assert.Equal(t, wrapper.Error(), message.Message)
case false:
assert.Equal(t, err.Error(), message.Message)
}
api.EncodeError(context.Background(), c.err, responseWriter)
assert.Equal(t, c.code, responseWriter.StatusCode())
if !c.hasBody {
return
}
message := body{}
jerr := json.Unmarshal(responseWriter.Body(), &message)
assert.NoError(t, jerr)
assert.NotEmpty(t, message.Message)
})
}
}
+91 -88
View File
@@ -10,268 +10,271 @@ import "github.com/absmach/supermq/pkg/errors"
// errors are logged twice.
var (
// ErrValidation indicates that an error was returned by the API.
ErrValidation = errors.New("something went wrong with the request")
ErrValidation = errors.NewRequestError("something went wrong with the request")
// ErrBearerToken indicates missing or invalid bearer user token.
ErrBearerToken = errors.New("missing or invalid bearer user token")
ErrBearerToken = errors.NewAuthNError("missing or invalid bearer user token")
// ErrBearerKey indicates missing or invalid bearer entity key.
ErrBearerKey = errors.New("missing or invalid bearer entity key")
ErrBearerKey = errors.NewAuthNError("missing or invalid bearer entity key")
// ErrMissingID indicates missing entity ID.
ErrMissingID = errors.New("missing entity id")
ErrMissingID = errors.NewRequestError("missing entity id")
// ErrMissingEntityID indicates missing entity ID.
ErrMissingEntityID = errors.New("missing entity id")
ErrMissingEntityID = errors.NewRequestError("missing entity id")
// ErrMissingClientID indicates missing client ID.
ErrMissingClientID = errors.New("missing cient id")
ErrMissingClientID = errors.NewRequestError("missing client id")
// ErrMissingChannelID indicates missing client ID.
ErrMissingChannelID = errors.New("missing channel id")
ErrMissingChannelID = errors.NewRequestError("missing channel id")
// ErrMissingConnectionType indicates missing connection tpye.
ErrMissingConnectionType = errors.New("missing connection type")
ErrMissingConnectionType = errors.NewRequestError("missing connection type")
// ErrMissingParentGroupID indicates missing parent group ID.
ErrMissingParentGroupID = errors.New("missing parent group id")
ErrMissingParentGroupID = errors.NewRequestError("missing parent group id")
// ErrMissingChildrenGroupIDs indicates missing children group IDs.
ErrMissingChildrenGroupIDs = errors.New("missing children group ids")
ErrMissingChildrenGroupIDs = errors.NewRequestError("missing children group ids")
// ErrSelfParentingNotAllowed indicates child id is same as parent id.
ErrSelfParentingNotAllowed = errors.New("self parenting not allowed")
ErrSelfParentingNotAllowed = errors.NewRequestError("self parenting not allowed")
// ErrInvalidChildGroupID indicates invalid child group ID.
ErrInvalidChildGroupID = errors.New("invalid child group id")
ErrInvalidChildGroupID = errors.NewRequestError("invalid child group id")
// ErrInvalidAuthKey indicates invalid auth key.
ErrInvalidAuthKey = errors.New("invalid auth key")
// ErrInvalidIDFormat indicates an invalid ID format.
ErrInvalidIDFormat = errors.New("invalid id format provided")
ErrInvalidIDFormat = errors.NewRequestError("invalid id format provided")
// ErrNameSize indicates that name size exceeds the max.
ErrNameSize = errors.New("invalid name size")
ErrNameSize = errors.NewRequestError("invalid name size")
// ErrEmailSize indicates that email size exceeds the max.
ErrEmailSize = errors.New("invalid email size")
ErrEmailSize = errors.NewRequestError("invalid email size")
// ErrInvalidRole indicates that an invalid role.
ErrInvalidRole = errors.New("invalid client role")
ErrInvalidRole = errors.NewRequestError("invalid client role")
// ErrLimitSize indicates that an invalid limit.
ErrLimitSize = errors.New("invalid limit size")
ErrLimitSize = errors.NewRequestError("invalid limit size")
// ErrLevel indicates that an invalid level.
ErrLevel = errors.New("invalid level")
ErrLevel = errors.NewRequestError("invalid level")
// ErrOffsetSize indicates an invalid offset.
ErrOffsetSize = errors.New("invalid offset size")
ErrOffsetSize = errors.NewRequestError("invalid offset size")
// ErrInvalidOrder indicates an invalid list order.
ErrInvalidOrder = errors.New("invalid list order provided")
ErrInvalidOrder = errors.NewRequestError("invalid list order provided")
// ErrInvalidDirection indicates an invalid list direction.
ErrInvalidDirection = errors.New("invalid list direction provided")
ErrInvalidDirection = errors.NewRequestError("invalid list direction provided")
// ErrInvalidMemberKind indicates an invalid member kind.
ErrInvalidMemberKind = errors.New("invalid member kind")
ErrInvalidMemberKind = errors.NewRequestError("invalid member kind")
// ErrEmptyList indicates that entity data is empty.
ErrEmptyList = errors.New("empty list provided")
ErrEmptyList = errors.NewRequestError("empty list provided")
// ErrMissingRoleName indicates that role name is empty.
ErrMissingRoleName = errors.New("empty role name")
ErrMissingRoleName = errors.NewRequestError("empty role name")
// ErrMissingRoleID indicates that role id is empty.
ErrMissingRoleID = errors.New("empty role id")
ErrMissingRoleID = errors.NewRequestError("empty role id")
// ErrMissingRoleOperations indicates that role operations are empty.
ErrMissingRoleOperations = errors.New("empty role operations")
ErrMissingRoleOperations = errors.NewRequestError("empty role operations")
// ErrMissingRoleMembers indicates that role members are empty.
ErrMissingRoleMembers = errors.New("empty role members")
ErrMissingRoleMembers = errors.NewRequestError("empty role members")
// ErrMalformedPolicy indicates that policies are malformed.
ErrMalformedPolicy = errors.New("malformed policy")
ErrMalformedPolicy = errors.NewRequestError("malformed policy")
// ErrMissingPolicySub indicates that policies are subject.
ErrMissingPolicySub = errors.New("malformed policy subject")
ErrMissingPolicySub = errors.NewRequestError("malformed policy subject")
// ErrMissingPolicyObj indicates missing policies object.
ErrMissingPolicyObj = errors.New("malformed policy object")
ErrMissingPolicyObj = errors.NewRequestError("malformed policy object")
// ErrMalformedPolicyAct indicates missing policies action.
ErrMalformedPolicyAct = errors.New("malformed policy action")
ErrMalformedPolicyAct = errors.NewRequestError("malformed policy action")
// ErrMissingPolicyEntityType indicates missing policies entity type.
ErrMissingPolicyEntityType = errors.New("missing policy entity type")
ErrMissingPolicyEntityType = errors.NewRequestError("missing policy entity type")
// ErrMalformedPolicyPer indicates missing policies relation.
ErrMalformedPolicyPer = errors.New("malformed policy permission")
ErrMalformedPolicyPer = errors.NewRequestError("malformed policy permission")
// ErrMissingCertData indicates missing cert data (ttl).
ErrMissingCertData = errors.New("missing certificate data")
ErrMissingCertData = errors.NewRequestError("missing certificate data")
// ErrInvalidCertData indicates invalid cert data (ttl).
ErrInvalidCertData = errors.New("invalid certificate data")
ErrInvalidCertData = errors.NewRequestError("invalid certificate data")
// ErrInvalidTopic indicates an invalid subscription topic.
ErrInvalidTopic = errors.New("invalid Subscription topic")
ErrInvalidTopic = errors.NewRequestError("invalid Subscription topic")
// ErrInvalidContact indicates an invalid subscription contract.
ErrInvalidContact = errors.New("invalid Subscription contact")
ErrInvalidContact = errors.NewRequestError("invalid Subscription contact")
// ErrMissingEmail indicates missing email.
ErrMissingEmail = errors.New("missing email")
ErrMissingEmail = errors.NewRequestError("missing email")
// ErrInvalidEmail indicates missing email.
ErrInvalidEmail = errors.New("invalid email")
ErrInvalidEmail = errors.NewRequestError("invalid email")
// ErrMissingHost indicates missing host.
ErrMissingHost = errors.New("missing host")
ErrMissingHost = errors.NewRequestError("missing host")
// ErrMissingPass indicates missing password.
ErrMissingPass = errors.New("missing password")
ErrMissingPass = errors.NewRequestError("missing password")
// ErrMissingConfPass indicates missing conf password.
ErrMissingConfPass = errors.New("missing conf password")
ErrMissingConfPass = errors.NewRequestError("missing conf password")
// ErrInvalidResetPass indicates an invalid reset password.
ErrInvalidResetPass = errors.New("invalid reset password")
ErrInvalidResetPass = errors.NewRequestError("invalid reset password")
// ErrInvalidComparator indicates an invalid comparator.
ErrInvalidComparator = errors.New("invalid comparator")
ErrInvalidComparator = errors.NewRequestError("invalid comparator")
// ErrMissingMemberIDs indicates missing member ids.
ErrMissingMemberIDs = errors.New("missing member ids")
ErrMissingMemberIDs = errors.NewRequestError("missing member ids")
// ErrMissingMemberType indicates missing group member type.
ErrMissingMemberType = errors.New("missing group member type")
ErrMissingMemberType = errors.NewRequestError("missing group member type")
// ErrMissingMemberKind indicates missing group member kind.
ErrMissingMemberKind = errors.New("missing group member kind")
ErrMissingMemberKind = errors.NewRequestError("missing group member kind")
// ErrMissingRelation indicates missing relation.
ErrMissingRelation = errors.New("missing relation")
ErrMissingRelation = errors.NewRequestError("missing relation")
// ErrInvalidRelation indicates an invalid relation.
ErrInvalidRelation = errors.New("invalid relation")
ErrInvalidRelation = errors.NewRequestError("invalid relation")
// ErrInvalidAPIKey indicates an invalid API key type.
ErrInvalidAPIKey = errors.New("invalid api key type")
ErrInvalidAPIKey = errors.NewRequestError("invalid api key type")
// ErrInvitationState indicates an invalid invitation state.
ErrInvitationState = errors.New("invalid invitation state")
ErrInvitationState = errors.NewRequestError("invalid invitation state")
// ErrMissingIdentity indicates missing entity Identity.
ErrMissingIdentity = errors.New("missing entity identity")
ErrMissingIdentity = errors.NewRequestError("missing entity identity")
// ErrMissingSecret indicates missing secret.
ErrMissingSecret = errors.New("missing secret")
ErrMissingSecret = errors.NewRequestError("missing secret")
// ErrPasswordFormat indicates weak password.
ErrPasswordFormat = errors.New("password does not meet the requirements")
ErrPasswordFormat = errors.NewRequestError("password does not meet the requirements")
// ErrMissingName indicates missing identity name.
ErrMissingName = errors.New("missing identity name")
ErrMissingName = errors.NewRequestError("missing identity name")
// ErrMissingRoute indicates missing route.
ErrMissingRoute = errors.New("missing route")
ErrMissingRoute = errors.NewRequestError("missing route")
// ErrInvalidLevel indicates an invalid group level.
ErrInvalidLevel = errors.New("invalid group level (should be between 0 and 5)")
ErrInvalidLevel = errors.NewRequestError("invalid group level (should be between 0 and 5)")
// ErrNotFoundParam indicates that the parameter was not found in the query.
ErrNotFoundParam = errors.New("parameter not found in the query")
ErrNotFoundParam = errors.NewRequestError("parameter not found in the query")
// ErrInvalidQueryParams indicates invalid query parameters.
ErrInvalidQueryParams = errors.New("invalid query parameters")
ErrInvalidQueryParams = errors.NewRequestError("invalid query parameters")
// ErrInvalidVisibilityType indicates invalid visibility type.
ErrInvalidVisibilityType = errors.New("invalid visibility type")
ErrInvalidVisibilityType = errors.NewRequestError("invalid visibility type")
// ErrUnsupportedContentType indicates unacceptable or lack of Content-Type.
ErrUnsupportedContentType = errors.New("unsupported content type")
ErrUnsupportedContentType = errors.NewMediaTypeError("unsupported content type")
// ErrRollbackTx indicates failed to rollback transaction.
ErrRollbackTx = errors.New("failed to rollback transaction")
ErrRollbackTx = errors.NewRequestError("failed to rollback transaction")
// ErrInvalidAggregation indicates invalid aggregation value.
ErrInvalidAggregation = errors.New("invalid aggregation value")
ErrInvalidAggregation = errors.NewRequestError("invalid aggregation value")
// ErrInvalidInterval indicates invalid interval value.
ErrInvalidInterval = errors.New("invalid interval value")
ErrInvalidInterval = errors.NewRequestError("invalid interval value")
// ErrMissingFrom indicates missing from value.
ErrMissingFrom = errors.New("missing from time value")
ErrMissingFrom = errors.NewRequestError("missing from time value")
// ErrMissingTo indicates missing to value.
ErrMissingTo = errors.New("missing to time value")
ErrMissingTo = errors.NewRequestError("missing to time value")
// ErrEmptyMessage indicates empty message.
ErrEmptyMessage = errors.New("empty message")
ErrEmptyMessage = errors.NewRequestError("empty message")
// ErrMissingEntityType indicates missing entity type.
ErrMissingEntityType = errors.New("missing entity type")
ErrMissingEntityType = errors.NewRequestError("missing entity type")
// ErrInvalidEntityType indicates invalid entity type.
ErrInvalidEntityType = errors.New("invalid entity type")
ErrInvalidEntityType = errors.NewRequestError("invalid entity type")
// ErrInvalidTimeFormat indicates invalid time format i.e not unix time.
ErrInvalidTimeFormat = errors.New("invalid time format use unix time")
ErrInvalidTimeFormat = errors.NewRequestError("invalid time format use unix time")
// ErrEmptySearchQuery indicates search query should not be empty.
ErrEmptySearchQuery = errors.New("search query must not be empty")
ErrEmptySearchQuery = errors.NewRequestError("search query must not be empty")
// ErrLenSearchQuery indicates search query length.
ErrLenSearchQuery = errors.New("search query must be at least 3 characters")
ErrLenSearchQuery = errors.NewRequestError("search query must be at least 3 characters")
// ErrMissingDomainID indicates missing domainID.
ErrMissingDomainID = errors.New("missing domainID")
ErrMissingDomainID = errors.NewRequestError("missing domainID")
// ErrMissingUsername indicates missing user name.
ErrMissingUsername = errors.New("missing username")
ErrMissingUsername = errors.NewRequestError("missing username")
// ErrInvalidUsername indicates invalid user name.
ErrInvalidUsername = errors.New("invalid username")
ErrInvalidUsername = errors.NewRequestError("invalid username")
// ErrMissingFirstName indicates missing first name.
ErrMissingFirstName = errors.New("missing first name")
ErrMissingFirstName = errors.NewRequestError("missing first name")
// ErrMissingLastName indicates missing last name.
ErrMissingLastName = errors.New("missing last name")
ErrMissingLastName = errors.NewRequestError("missing last name")
// ErrInvalidProfilePictureURL indicates that the profile picture url is invalid.
ErrInvalidProfilePictureURL = errors.New("invalid profile picture url")
ErrInvalidProfilePictureURL = errors.NewRequestError("invalid profile picture url")
ErrMultipleEntitiesFilter = errors.New("multiple entities are provided in filter are not supported")
ErrMultipleEntitiesFilter = errors.NewRequestError("multiple entities are provided in filter are not supported")
// ErrMissingDescription indicates missing description.
ErrMissingDescription = errors.New("missing description")
ErrMissingDescription = errors.NewRequestError("missing description")
// ErrUnsupportedTokenType indicates that this type of token is not supported.
ErrUnsupportedTokenType = errors.New("unsupported content token type")
ErrUnsupportedTokenType = errors.NewRequestError("unsupported content token type")
// ErrMissingUserID indicates missing user ID.
ErrMissingUserID = errors.New("missing user id")
ErrMissingUserID = errors.NewRequestError("missing user id")
// ErrMissingPATID indicates missing pat ID.
ErrMissingPATID = errors.New("missing pat id")
ErrMissingPATID = errors.NewRequestError("missing pat id")
// ErrInvalidNameFormat indicates invalid name format.
ErrInvalidNameFormat = errors.New("invalid name format")
ErrInvalidNameFormat = errors.NewRequestError("invalid name format")
// ErrInvalidRouteFormat indicates invalid route format.
ErrInvalidRouteFormat = errors.New("invalid route format")
ErrInvalidRouteFormat = errors.NewRequestError("invalid route format")
// ErrMissingUsernameEmail indicates missing user name / email.
ErrMissingUsernameEmail = errors.New("missing username / email")
ErrMissingUsernameEmail = errors.NewRequestError("missing username / email")
// ErrInvalidVerification indicates invalid email verification.
ErrInvalidVerification = errors.New("invalid verification")
ErrInvalidVerification = errors.NewRequestError("invalid verification")
// ErrEmailNotVerified indicates invalid email not verified.
ErrEmailNotVerified = errors.New("email not verified")
ErrEmailNotVerified = errors.NewRequestError("email not verified")
// ErrMalformedRequest indicates malformed request body.
ErrMalformedRequestBody = errors.NewRequestError("request body is not a valid JSON, expecting a valid JSON")
)