From 37676cedb79cd97f5adadceb84a934480f8750e6 Mon Sep 17 00:00:00 2001 From: Caleb Jasik Date: Tue, 6 May 2025 10:51:49 -0500 Subject: [PATCH 1/4] Return APIErrors directly instead of as a stringified error --- client.go | 8 ++++---- message/message.go | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index b5285d3..a95ace3 100644 --- a/client.go +++ b/client.go @@ -164,8 +164,8 @@ func (c *Client) Enroll(ctx context.Context, logger logrus.FieldLogger, code str } // Check for any errors returned by the API - if err := r.Errors.ToError(); err != nil { - return nil, nil, nil, nil, &APIError{e: fmt.Errorf("unexpected error during enrollment: %v", err), ReqID: reqID} + if err := r.Errors; err != nil { + return nil, nil, nil, nil, err } meta := &EnrollMeta{ @@ -412,7 +412,7 @@ func (c *Client) streamingPostDNClient(ctx context.Context, reqType string, valu if err := json.Unmarshal(respBody, &errors); err != nil { sc.err.Store(fmt.Errorf("dnclient endpoint returned bad status code '%d', body: %s", resp.StatusCode, respBody)) } else { - sc.err.Store(errors.Errors.ToError()) + sc.err.Store(errors.Errors) } } }() @@ -459,7 +459,7 @@ func (c *Client) postDNClient(ctx context.Context, reqType string, value []byte, if err := json.Unmarshal(respBody, &errors); err != nil { return nil, fmt.Errorf("dnclient endpoint returned bad status code '%d', body: %s", resp.StatusCode, respBody) } - return nil, errors.Errors.ToError() + return nil, errors.Errors } } diff --git a/message/message.go b/message/message.go index d8b0227..37426c6 100644 --- a/message/message.go +++ b/message/message.go @@ -167,9 +167,9 @@ type APIError struct { type APIErrors []APIError -func (errs APIErrors) ToError() error { +func (errs APIErrors) Error() string { if len(errs) == 0 { - return nil + return "" } s := make([]string, len(errs)) @@ -177,7 +177,7 @@ func (errs APIErrors) ToError() error { s[i] = errs[i].Message } - return errors.New(strings.Join(s, ", ")) + return strings.Join(s, ", ") } // NetworkCurve represents the network curve specified by the API. From 6bae8dc8869949cfe810f5e319ecde0effd8a825 Mon Sep 17 00:00:00 2001 From: Caleb Jasik Date: Wed, 7 May 2025 13:36:42 -0500 Subject: [PATCH 2/4] Back out "Return APIErrors directly instead of as a stringified error" This backs out commit 37676cedb79cd97f5adadceb84a934480f8750e6. --- client.go | 8 ++++---- message/message.go | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index a95ace3..b5285d3 100644 --- a/client.go +++ b/client.go @@ -164,8 +164,8 @@ func (c *Client) Enroll(ctx context.Context, logger logrus.FieldLogger, code str } // Check for any errors returned by the API - if err := r.Errors; err != nil { - return nil, nil, nil, nil, err + if err := r.Errors.ToError(); err != nil { + return nil, nil, nil, nil, &APIError{e: fmt.Errorf("unexpected error during enrollment: %v", err), ReqID: reqID} } meta := &EnrollMeta{ @@ -412,7 +412,7 @@ func (c *Client) streamingPostDNClient(ctx context.Context, reqType string, valu if err := json.Unmarshal(respBody, &errors); err != nil { sc.err.Store(fmt.Errorf("dnclient endpoint returned bad status code '%d', body: %s", resp.StatusCode, respBody)) } else { - sc.err.Store(errors.Errors) + sc.err.Store(errors.Errors.ToError()) } } }() @@ -459,7 +459,7 @@ func (c *Client) postDNClient(ctx context.Context, reqType string, value []byte, if err := json.Unmarshal(respBody, &errors); err != nil { return nil, fmt.Errorf("dnclient endpoint returned bad status code '%d', body: %s", resp.StatusCode, respBody) } - return nil, errors.Errors + return nil, errors.Errors.ToError() } } diff --git a/message/message.go b/message/message.go index 37426c6..d8b0227 100644 --- a/message/message.go +++ b/message/message.go @@ -167,9 +167,9 @@ type APIError struct { type APIErrors []APIError -func (errs APIErrors) Error() string { +func (errs APIErrors) ToError() error { if len(errs) == 0 { - return "" + return nil } s := make([]string, len(errs)) @@ -177,7 +177,7 @@ func (errs APIErrors) Error() string { s[i] = errs[i].Message } - return strings.Join(s, ", ") + return errors.New(strings.Join(s, ", ")) } // NetworkCurve represents the network curve specified by the API. From c83a979e6f59e1691e215d35ec65d4807921175c Mon Sep 17 00:00:00 2001 From: Caleb Jasik Date: Wed, 7 May 2025 13:44:12 -0500 Subject: [PATCH 3/4] Return a custom error if we get an invalid enrollment code error --- client.go | 18 +++++++++++------- client_test.go | 6 ++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index b5285d3..1648cfe 100644 --- a/client.go +++ b/client.go @@ -79,11 +79,8 @@ func (e *APIError) Unwrap() error { return e.e } -type InvalidCredentialsError struct{} - -func (e InvalidCredentialsError) Error() string { - return "invalid credentials" -} +var InvalidCredentialsError = fmt.Errorf("invalid credentials") +var InvalidCodeError = fmt.Errorf("invalid enrollment code") type EnrollMeta struct { OrganizationID string @@ -163,6 +160,13 @@ func (c *Client) Enroll(ctx context.Context, logger logrus.FieldLogger, code str return nil, nil, nil, nil, &APIError{e: fmt.Errorf("error decoding JSON response: %s\nbody: %s", err, b), ReqID: reqID} } + // Check for *only* an "invalid code" error returned by the API + if len(r.Errors) == 1 { + if err := r.Errors[0]; err.Path == "code" && err.Code == "ERR_INVALID_VALUE" { + return nil, nil, nil, nil, &APIError{e: InvalidCodeError, ReqID: reqID} + } + } + // Check for any errors returned by the API if err := r.Errors.ToError(); err != nil { return nil, nil, nil, nil, &APIError{e: fmt.Errorf("unexpected error during enrollment: %v", err), ReqID: reqID} @@ -404,7 +408,7 @@ func (c *Client) streamingPostDNClient(ctx context.Context, reqType string, valu case http.StatusOK: sc.respBytes = respBody case http.StatusUnauthorized: - sc.err.Store(InvalidCredentialsError{}) + sc.err.Store(InvalidCredentialsError) default: var errors struct { Errors message.APIErrors @@ -451,7 +455,7 @@ func (c *Client) postDNClient(ctx context.Context, reqType string, value []byte, case http.StatusOK: return respBody, nil case http.StatusUnauthorized: - return nil, InvalidCredentialsError{} + return nil, InvalidCredentialsError default: var errors struct { Errors message.APIErrors diff --git a/client_test.go b/client_test.go index 6be7a92..0dbc9b3 100644 --- a/client_test.go +++ b/client_test.go @@ -237,8 +237,7 @@ func TestDoUpdate(t *testing.T) { defer cancel() _, err = c.CheckForUpdate(ctx, invalidCreds) assert.Error(t, err) - invalidCredsErrorType := InvalidCredentialsError{} - assert.ErrorAs(t, err, &invalidCredsErrorType) + assert.ErrorAs(t, err, &InvalidCredentialsError) serverErrs := ts.Errors() // This consumes/resets the server errors require.Len(t, serverErrs, 1) @@ -427,8 +426,7 @@ func TestDoUpdate_P256(t *testing.T) { defer cancel() _, err = c.CheckForUpdate(ctx, invalidCreds) assert.Error(t, err) - invalidCredsErrorType := InvalidCredentialsError{} - assert.ErrorAs(t, err, &invalidCredsErrorType) + assert.ErrorAs(t, err, &InvalidCredentialsError) serverErrs := ts.Errors() // This consumes/resets the server errors require.Len(t, serverErrs, 1) From d3a1c7457ce9385cefbabb6146f424902d29cb99 Mon Sep 17 00:00:00 2001 From: Caleb Jasik Date: Fri, 9 May 2025 11:17:01 -0500 Subject: [PATCH 4/4] Alter the naming pattern for the errors --- client.go | 10 +++++----- client_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index 1648cfe..885700c 100644 --- a/client.go +++ b/client.go @@ -79,8 +79,8 @@ func (e *APIError) Unwrap() error { return e.e } -var InvalidCredentialsError = fmt.Errorf("invalid credentials") -var InvalidCodeError = fmt.Errorf("invalid enrollment code") +var ErrInvalidCredentials = fmt.Errorf("invalid credentials") +var ErrInvalidCode = fmt.Errorf("invalid enrollment code") type EnrollMeta struct { OrganizationID string @@ -163,7 +163,7 @@ func (c *Client) Enroll(ctx context.Context, logger logrus.FieldLogger, code str // Check for *only* an "invalid code" error returned by the API if len(r.Errors) == 1 { if err := r.Errors[0]; err.Path == "code" && err.Code == "ERR_INVALID_VALUE" { - return nil, nil, nil, nil, &APIError{e: InvalidCodeError, ReqID: reqID} + return nil, nil, nil, nil, &APIError{e: ErrInvalidCode, ReqID: reqID} } } @@ -408,7 +408,7 @@ func (c *Client) streamingPostDNClient(ctx context.Context, reqType string, valu case http.StatusOK: sc.respBytes = respBody case http.StatusUnauthorized: - sc.err.Store(InvalidCredentialsError) + sc.err.Store(ErrInvalidCredentials) default: var errors struct { Errors message.APIErrors @@ -455,7 +455,7 @@ func (c *Client) postDNClient(ctx context.Context, reqType string, value []byte, case http.StatusOK: return respBody, nil case http.StatusUnauthorized: - return nil, InvalidCredentialsError + return nil, ErrInvalidCredentials default: var errors struct { Errors message.APIErrors diff --git a/client_test.go b/client_test.go index 0dbc9b3..3b58824 100644 --- a/client_test.go +++ b/client_test.go @@ -237,7 +237,7 @@ func TestDoUpdate(t *testing.T) { defer cancel() _, err = c.CheckForUpdate(ctx, invalidCreds) assert.Error(t, err) - assert.ErrorAs(t, err, &InvalidCredentialsError) + assert.ErrorIs(t, err, ErrInvalidCredentials) serverErrs := ts.Errors() // This consumes/resets the server errors require.Len(t, serverErrs, 1) @@ -426,7 +426,7 @@ func TestDoUpdate_P256(t *testing.T) { defer cancel() _, err = c.CheckForUpdate(ctx, invalidCreds) assert.Error(t, err) - assert.ErrorAs(t, err, &InvalidCredentialsError) + assert.ErrorIs(t, err, ErrInvalidCredentials) serverErrs := ts.Errors() // This consumes/resets the server errors require.Len(t, serverErrs, 1)