diff --git a/errors/pluginerrors.go b/errors/pluginerrors.go index cc851e1f9..0ec7f4c53 100644 --- a/errors/pluginerrors.go +++ b/errors/pluginerrors.go @@ -105,11 +105,11 @@ var ( Description: `The manifest is invalid. Please validate the manifest is correctly formatted.`, }) - // ErrorCodeReferrersNotFound is returned if there is no ReferrerStore set. - ErrorCodeReferrersNotFound = Register("errcode", ErrorDescriptor{ - Value: "REFERRERS_NOT_FOUND", - Message: "referrers not found", - Description: "No referrers are found. Please verify the subject has attached expected artifacts and refer to https://ratify.dev/docs/reference/store/ to investigate Referrer Store configuration.", + // ErrorCodeNoVerifierReport is returned if there is no ReferrerStore set. + ErrorCodeNoVerifierReport = Register("errcode", ErrorDescriptor{ + Value: "NO_VERIFIER_REPORT", + Message: "no verifier report", + Description: "No verifier report was generated. This might be due to various factors, such as lack of artifacts attached to the image, a misconfiguration in the Referrer Store preventing access to the registry, or the absence of appropriate verifiers corresponding to the referenced image artifacts.", }) // Generic errors happen in plugins diff --git a/errors/types.go b/errors/types.go index 8b4529e83..3a211c80a 100644 --- a/errors/types.go +++ b/errors/types.go @@ -68,6 +68,7 @@ type Error struct { PluginName string `json:"pluginName,omitempty"` LinkToDoc string `json:"linkToDoc,omitempty"` Stack string `json:"stack,omitempty"` + Description string `json:"description,omitempty"` } // ErrorDescriptor provides relevant information about a given error code. @@ -124,6 +125,11 @@ func (ec ErrorCode) Message() string { return ec.Descriptor().Message } +// Description returned the description of this error code. +func (ec ErrorCode) Description() string { + return ec.Descriptor().Description +} + // String returns the canonical identifier for this error code. func (ec ErrorCode) String() string { return ec.Descriptor().Value @@ -149,6 +155,10 @@ func (ec ErrorCode) WithLinkToDoc(link string) Error { return newError(ec, ec.Message()).WithLinkToDoc(link) } +func (ec ErrorCode) WithDescription() Error { + return newError(ec, ec.Message()).WithDescription() +} + // WithPluginName returns a new Error object with pluginName set. func (ec ErrorCode) WithPluginName(pluginName string) Error { return newError(ec, ec.Message()).WithPluginName(pluginName) @@ -223,6 +233,10 @@ func (e Error) Error() string { errStr += fmt.Sprintf(", Detail: %v", e.Detail) } + if e.Description != "" { + errStr += fmt.Sprintf(", Description: %v", e.Description) + } + if e.Stack != "" { errStr += fmt.Sprintf(", Stack trace: %s", e.Stack) } @@ -261,6 +275,11 @@ func (e Error) WithLinkToDoc(link string) Error { return e } +func (e Error) WithDescription() Error { + e.Description = e.Code.Description() + return e +} + // IsEmpty returns true if the error is empty. func (e Error) IsEmpty() bool { return e == emptyError diff --git a/errors/types_test.go b/errors/types_test.go index 4dc5dd6ce..5e97400d1 100644 --- a/errors/types_test.go +++ b/errors/types_test.go @@ -126,6 +126,13 @@ func TestWithPluginName(t *testing.T) { } } +func TestWithDescription(t *testing.T) { + err := testEC.WithDescription() + if err.Description != testDescription { + t.Fatalf("expected description: %s, got: %s", testDescription, err.Description) + } +} + func TestIs(t *testing.T) { err := testEC.WithDetail(testDetail) result := err.Is(err) @@ -161,7 +168,7 @@ func TestIsEmpty(t *testing.T) { } func TestError_Error(t *testing.T) { - err := testEC.WithPluginName(testPluginName).WithComponentType(testComponentType).WithLinkToDoc(testLink).WithDetail(testDetail).WithError(Error{}) + err := testEC.WithPluginName(testPluginName).WithComponentType(testComponentType).WithLinkToDoc(testLink).WithDetail(testDetail).WithError(Error{}).WithDescription() result := err.Error() if !strings.HasPrefix(result, testErrorString) { t.Fatalf("expected string starts with: %s, but got: %s", testErrorString, result) diff --git a/pkg/executor/core/executor.go b/pkg/executor/core/executor.go index 08e89bece..f1cec9d79 100644 --- a/pkg/executor/core/executor.go +++ b/pkg/executor/core/executor.go @@ -83,7 +83,7 @@ func (executor Executor) verifySubjectInternal(ctx context.Context, verifyParame } if executor.PolicyEnforcer.GetPolicyType(ctx) == pt.ConfigPolicy { if len(verifierReports) == 0 { - return types.VerifyResult{}, errors.ErrorCodeReferrersNotFound.WithComponentType(errors.Executor) + return types.VerifyResult{}, errors.ErrorCodeNoVerifierReport.WithComponentType(errors.Executor).WithDescription() } } // If it requires embedded Rego Policy Engine make the decision, execute diff --git a/pkg/executor/core/executor_test.go b/pkg/executor/core/executor_test.go index 36edaff76..a4fbb1518 100644 --- a/pkg/executor/core/executor_test.go +++ b/pkg/executor/core/executor_test.go @@ -188,7 +188,7 @@ func TestVerifySubjectInternal_ResolveSubjectDescriptor_Success(t *testing.T) { Subject: "localhost:5000/net-monitor:v1", } - if _, err := executor.verifySubjectInternal(context.Background(), verifyParameters); !errors.Is(err, ratifyerrors.ErrorCodeReferrersNotFound.WithDetail("")) { + if _, err := executor.verifySubjectInternal(context.Background(), verifyParameters); !errors.Is(err, ratifyerrors.ErrorCodeNoVerifierReport.WithDetail("")) { t.Fatalf("expected ErrReferrersNotFound actual %v", err) } } @@ -214,7 +214,7 @@ func TestVerifySubjectInternal_Verify_NoReferrers(t *testing.T) { Subject: "localhost:5000/net-monitor:v1", } - if _, err := ex.verifySubjectInternal(context.Background(), verifyParameters); !errors.Is(err, ratifyerrors.ErrorCodeReferrersNotFound.WithDetail("")) { + if _, err := ex.verifySubjectInternal(context.Background(), verifyParameters); !errors.Is(err, ratifyerrors.ErrorCodeNoVerifierReport.WithDetail("")) { t.Fatalf("expected ErrReferrersNotFound actual %v", err) } }