mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
NOISSUE - Add internal type to find NestError and Add Auth key algorithm to journal docker compose (#3304)
Signed-off-by: Arvindh <arvindh91@gmail.com>
This commit is contained in:
@@ -270,8 +270,8 @@ jobs:
|
||||
run: |
|
||||
modules=()
|
||||
|
||||
if [[ "${{ steps.changes.outputs.workflow }}" == "true" ]]; then
|
||||
# If workflow changed, test everything
|
||||
if [[ "${{ steps.changes.outputs.workflow }}" == "true" || "${{ steps.changes.outputs.pkg-errors }}" == "true" ]]; then
|
||||
# If workflow or pkg/errors changed, test everything
|
||||
modules=("auth" "channels" "cli" "clients" "coap" "domains" "groups" "http" "internal" "journal" "logger" "mqtt" "pkg-errors" "pkg-events" "pkg-grpcclient" "pkg-messaging" "pkg-sdk" "pkg-transformers" "pkg-ulid" "pkg-uuid" "users" "ws" "notifications" "api" "consumers" "readers")
|
||||
else
|
||||
# Add only changed modules
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/absmach/supermq/auth/tokenizer/asymmetric"
|
||||
smqerrors "github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/lestrrat-go/jwx/v2/jwa"
|
||||
"github.com/lestrrat-go/jwx/v2/jwk"
|
||||
"github.com/lestrrat-go/jwx/v2/jwt"
|
||||
@@ -58,7 +59,7 @@ func TestNewKeyManager(t *testing.T) {
|
||||
name string
|
||||
setupKey func() string
|
||||
expectErr bool
|
||||
errContains string
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "valid PEM key",
|
||||
@@ -85,7 +86,7 @@ func TestNewKeyManager(t *testing.T) {
|
||||
return filepath.Join(tmpDir, "nonexistent.key")
|
||||
},
|
||||
expectErr: true,
|
||||
errContains: "failed to load private key",
|
||||
expectedErr: smqerrors.New("failed to load private key"),
|
||||
},
|
||||
{
|
||||
name: "invalid key size",
|
||||
@@ -96,7 +97,7 @@ func TestNewKeyManager(t *testing.T) {
|
||||
return invalidPath
|
||||
},
|
||||
expectErr: true,
|
||||
errContains: "invalid ED25519 key size",
|
||||
expectedErr: smqerrors.New("invalid ED25519 key size"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -108,8 +109,8 @@ func TestNewKeyManager(t *testing.T) {
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(t, err)
|
||||
if tc.errContains != "" {
|
||||
assert.Contains(t, err.Error(), tc.errContains)
|
||||
if tc.expectedErr != nil {
|
||||
assert.True(t, smqerrors.Contains(err, tc.expectedErr))
|
||||
}
|
||||
assert.Nil(t, km)
|
||||
} else {
|
||||
|
||||
@@ -59,6 +59,7 @@ services:
|
||||
SMQ_AUTH_GRPC_CLIENT_CERT: ${SMQ_AUTH_GRPC_CLIENT_CERT:+/auth-grpc-client.crt}
|
||||
SMQ_AUTH_GRPC_CLIENT_KEY: ${SMQ_AUTH_GRPC_CLIENT_KEY:+/auth-grpc-client.key}
|
||||
SMQ_AUTH_GRPC_SERVER_CA_CERTS: ${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+/auth-grpc-server-ca.crt}
|
||||
SMQ_AUTH_KEYS_ALGORITHM: ${SMQ_AUTH_KEYS_ALGORITHM}
|
||||
SMQ_ES_URL: ${SMQ_ES_URL}
|
||||
SMQ_JAEGER_URL: ${SMQ_JAEGER_URL}
|
||||
SMQ_JAEGER_TRACE_RATIO: ${SMQ_JAEGER_TRACE_RATIO}
|
||||
|
||||
@@ -267,7 +267,7 @@ func TestPublish(t *testing.T) {
|
||||
err: errMalformedTopic,
|
||||
},
|
||||
{
|
||||
desc: "publish with malformwd subtopic",
|
||||
desc: "publish with malformed subtopic",
|
||||
topic: &malformedSubtopics,
|
||||
status: http.StatusBadRequest,
|
||||
password: clientKey,
|
||||
@@ -411,7 +411,7 @@ func TestPublish(t *testing.T) {
|
||||
authNErr: nil,
|
||||
authZRes: &grpcChannelsV1.AuthzRes{Authorized: true},
|
||||
authZErr: nil,
|
||||
publishErr: errors.New("failed to publish"),
|
||||
publishErr: errFailedPublishToMsgBroker,
|
||||
err: errFailedPublishToMsgBroker,
|
||||
},
|
||||
{
|
||||
@@ -453,7 +453,7 @@ func TestPublish(t *testing.T) {
|
||||
assert.Equal(t, tc.status, hpe.StatusCode())
|
||||
}
|
||||
if tc.err != nil {
|
||||
assert.Contains(t, err.Error(), tc.err.Error(), fmt.Sprintf("expected error containing: %v, got: %v", tc.err, err))
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error containing: %v, got: %v", tc.err, err))
|
||||
}
|
||||
authCall.Unset()
|
||||
repoCall.Unset()
|
||||
|
||||
+42
-68
@@ -3,10 +3,7 @@
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
const internalServiceError = "internal server error"
|
||||
|
||||
type NestError interface {
|
||||
Error
|
||||
@@ -22,31 +19,30 @@ func (e *customError) Embed(err error) error {
|
||||
|
||||
return &customError{
|
||||
msg: e.msg,
|
||||
err: fmt.Errorf("%w: %w", e.err, err),
|
||||
err: Wrap(err, e.err),
|
||||
}
|
||||
}
|
||||
|
||||
type nestableError interface {
|
||||
NestError
|
||||
isNestable()
|
||||
}
|
||||
|
||||
type RequestError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*RequestError)(nil)
|
||||
var _ nestableError = (*RequestError)(nil)
|
||||
|
||||
func NewRequestError(message string) NestError {
|
||||
return &RequestError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewRequestErrorWithErr(message string, err error) NestError {
|
||||
return &RequestError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,27 +53,23 @@ func (e *RequestError) Embed(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (*RequestError) isNestable() {}
|
||||
|
||||
type AuthNError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*AuthNError)(nil)
|
||||
var _ nestableError = (*AuthNError)(nil)
|
||||
|
||||
func NewAuthNError(message string) NestError {
|
||||
return &AuthNError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewAuthNErrorWithErr(message string, err error) NestError {
|
||||
return &AuthNError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +80,9 @@ func (e *AuthNError) Embed(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
var _ NestError = (*AuthZError)(nil)
|
||||
func (*AuthNError) isNestable() {}
|
||||
|
||||
var _ nestableError = (*AuthZError)(nil)
|
||||
|
||||
type AuthZError struct {
|
||||
customError
|
||||
@@ -103,43 +97,33 @@ func (e *AuthZError) Embed(err error) error {
|
||||
|
||||
func NewAuthZError(message string) NestError {
|
||||
return &AuthZError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewAuthZErrorWithErr(message string, err error) NestError {
|
||||
return &AuthZError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
func (*AuthZError) isNestable() {}
|
||||
|
||||
type InternalError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*InternalError)(nil)
|
||||
var _ nestableError = (*InternalError)(nil)
|
||||
|
||||
func NewInternalError() error {
|
||||
return &InternalError{
|
||||
customError: customError{
|
||||
msg: "internal server error",
|
||||
err: errors.New("internal server error"),
|
||||
},
|
||||
customError: newCustomError(internalServiceError),
|
||||
}
|
||||
}
|
||||
|
||||
func NewInternalErrorWithErr(err error) NestError {
|
||||
return &InternalError{
|
||||
customError: customError{
|
||||
msg: "internal server error",
|
||||
err: fmt.Errorf("%w: %w", errors.New("internal server error"), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(internalServiceError, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,27 +134,23 @@ func (e *InternalError) Embed(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (*InternalError) isNestable() {}
|
||||
|
||||
type ServiceError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*ServiceError)(nil)
|
||||
var _ nestableError = (*ServiceError)(nil)
|
||||
|
||||
func NewServiceError(message string) NestError {
|
||||
return &ServiceError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewServiceErrorWithErr(message string, err error) NestError {
|
||||
return &ServiceError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,27 +161,23 @@ func (e *ServiceError) Embed(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (*ServiceError) isNestable() {}
|
||||
|
||||
type MediaTypeError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*MediaTypeError)(nil)
|
||||
var _ nestableError = (*MediaTypeError)(nil)
|
||||
|
||||
func NewMediaTypeError(message string) NestError {
|
||||
return &MediaTypeError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewMediaTypeErrorWithErr(message string, err error) NestError {
|
||||
return &MediaTypeError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,27 +188,23 @@ func (e *MediaTypeError) Embed(err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (*MediaTypeError) isNestable() {}
|
||||
|
||||
type NotFoundError struct {
|
||||
customError
|
||||
}
|
||||
|
||||
var _ NestError = (*NotFoundError)(nil)
|
||||
var _ nestableError = (*NotFoundError)(nil)
|
||||
|
||||
func NewNotFoundError(message string) NestError {
|
||||
return &NotFoundError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: errors.New(message),
|
||||
},
|
||||
customError: newCustomError(message),
|
||||
}
|
||||
}
|
||||
|
||||
func NewNotFoundErrorWithErr(message string, err error) NestError {
|
||||
return &NotFoundError{
|
||||
customError: customError{
|
||||
msg: message,
|
||||
err: fmt.Errorf("%w: %w", errors.New(message), err),
|
||||
},
|
||||
customError: newCustomErrorWithError(message, err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,3 +214,5 @@ func (e *NotFoundError) Embed(err error) error {
|
||||
customError: *embedded.(*customError),
|
||||
}
|
||||
}
|
||||
|
||||
func (*NotFoundError) isNestable() {}
|
||||
|
||||
+20
-6
@@ -6,7 +6,6 @@ package errors
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Error specifies an API that must be fullfiled by error type.
|
||||
@@ -32,11 +31,25 @@ type customError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func newCustomError(msg string) customError {
|
||||
return customError{
|
||||
msg: msg,
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func newCustomErrorWithError(msg string, err error) customError {
|
||||
return customError{
|
||||
msg: msg,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// New returns an Error that formats as the given text.
|
||||
func New(text string) Error {
|
||||
return &customError{
|
||||
msg: text,
|
||||
err: errors.New(text),
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +60,7 @@ func (ce *customError) Error() string {
|
||||
if ce.err == nil {
|
||||
return ce.msg
|
||||
}
|
||||
return ce.err.Error()
|
||||
return ce.msg + " : " + ce.err.Error()
|
||||
}
|
||||
|
||||
func (ce *customError) Msg() string {
|
||||
@@ -66,6 +79,7 @@ func (ce *customError) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// Contains inspects if e2 error is contained in any layer of e1 error.
|
||||
func Contains(e1, e2 error) bool {
|
||||
if e1 == nil || e2 == nil {
|
||||
return e2 == e1
|
||||
@@ -86,15 +100,15 @@ func Wrap(wrapper, err error) error {
|
||||
if wrapper == nil || err == nil {
|
||||
return wrapper
|
||||
}
|
||||
if ne, ok := err.(NestError); ok {
|
||||
if ne, ok := err.(nestableError); ok {
|
||||
return ne.Embed(wrapper)
|
||||
}
|
||||
if ce, ok := wrapper.(NestError); ok {
|
||||
if ce, ok := wrapper.(nestableError); ok {
|
||||
return ce.Embed(err)
|
||||
}
|
||||
return &customError{
|
||||
msg: wrapper.Error(),
|
||||
err: fmt.Errorf("%w: %w", wrapper, err),
|
||||
err: cast(err),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,21 +41,21 @@ func TestError(t *testing.T) {
|
||||
desc: "level 1 wrapped error",
|
||||
err: wrap(1),
|
||||
msg: message(1),
|
||||
bytes: []byte(`{"message":"0"}`),
|
||||
bytes: []byte(`{"message":"1"}`),
|
||||
bytesErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "level 2 wrapped error",
|
||||
err: wrap(2),
|
||||
msg: message(2),
|
||||
bytes: []byte(`{"message":"0"}`),
|
||||
bytes: []byte(`{"message":"2"}`),
|
||||
bytesErr: nil,
|
||||
},
|
||||
{
|
||||
desc: fmt.Sprintf("level %d wrapped error", level),
|
||||
err: wrap(level),
|
||||
msg: message(level),
|
||||
bytes: []byte(`{"message":"0"}`),
|
||||
bytes: []byte(`{"message":"10"}`),
|
||||
bytesErr: nil,
|
||||
},
|
||||
{
|
||||
@@ -80,6 +80,9 @@ func TestError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
internalErr1 := errors.New("some internal error 1")
|
||||
internalErr2 := errors.New("some internal error 2")
|
||||
internalErr3 := errors.New("some internal error 3")
|
||||
cases := []struct {
|
||||
desc string
|
||||
container error
|
||||
@@ -164,6 +167,42 @@ func TestContains(t *testing.T) {
|
||||
contained: err0,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by adding error in creation",
|
||||
container: errors.NewAuthNErrorWithErr("failed to authenticate", internalErr1),
|
||||
contained: internalErr1,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by adding error in creation (middle)",
|
||||
container: errors.Wrap(errors.NewAuthNErrorWithErr("failed to authenticate", internalErr1), internalErr2),
|
||||
contained: internalErr2,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by adding error in creation",
|
||||
container: errors.Wrap(errors.Wrap(errors.NewAuthNErrorWithErr("failed to authenticate", internalErr1), internalErr2), internalErr3),
|
||||
contained: internalErr1,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by adding error in creation (middle chain)",
|
||||
container: errors.Wrap(errors.Wrap(errors.NewAuthNErrorWithErr("failed to authenticate", internalErr1), internalErr2), internalErr3),
|
||||
contained: internalErr2,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by adding error in creation (outer chain)",
|
||||
container: errors.Wrap(errors.Wrap(errors.NewAuthNErrorWithErr("failed to authenticate", internalErr1), internalErr2), internalErr3),
|
||||
contained: internalErr3,
|
||||
contains: true,
|
||||
},
|
||||
{
|
||||
desc: "check nested errors contains errors by wrapping",
|
||||
container: errors.Wrap(errors.NewAuthNError("failed to authenticate"), internalErr1),
|
||||
contained: internalErr1,
|
||||
contains: true,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.desc, func(t *testing.T) {
|
||||
@@ -286,8 +325,8 @@ func TestUnwrap(t *testing.T) {
|
||||
{
|
||||
desc: "err 1 wraped err 2",
|
||||
err: errors.Wrap(err1, err2),
|
||||
wrapper: err2,
|
||||
wrapped: fmt.Errorf("%w: %w", err2, err1),
|
||||
wrapper: err1,
|
||||
wrapped: err2,
|
||||
},
|
||||
{
|
||||
desc: "nil wraps nil",
|
||||
@@ -334,10 +373,10 @@ func wrap(level int) error {
|
||||
}
|
||||
|
||||
// message generates error message of wrap() generated wrapper error.
|
||||
// The error message format is now "innermost: ... : outermost" due to fmt.Errorf wrapping.
|
||||
// The error message format is "outermost : ... : innermost".
|
||||
func message(level int) string {
|
||||
if level == 0 {
|
||||
if level <= 0 {
|
||||
return "0"
|
||||
}
|
||||
return message(level-1) + ": " + strconv.Itoa(level)
|
||||
return strconv.Itoa(level) + " : " + message(level-1)
|
||||
}
|
||||
|
||||
+2
-2
@@ -694,7 +694,7 @@ func TestPublish(t *testing.T) {
|
||||
session: &sessionClient,
|
||||
topic: wrongCharSubtopics,
|
||||
payload: payload,
|
||||
err: messaging.ErrMalformedTopic,
|
||||
err: messaging.ErrMalformedSubtopic,
|
||||
},
|
||||
{
|
||||
desc: "publish with subtopic",
|
||||
@@ -731,7 +731,7 @@ func TestPublish(t *testing.T) {
|
||||
repoCall := publisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
err := handler.Publish(ctx, &tc.topic, &tc.payload)
|
||||
if tc.err != nil {
|
||||
assert.Contains(t, err.Error(), tc.err.Error(), fmt.Sprintf("expected error message to contain: %v, got: %v", tc.err, err))
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error message to contain: %v, got: %v", tc.err, err))
|
||||
}
|
||||
repoCall.Unset()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user