Repository: cloudflare/cloudflare-go
Pull request #1047 (2022-08-17 00:46:08)

Add some error type convenience functions for mocking and inspection
## Description

Provide the ability to create the `RequestError`, etc types in other packages with the underlying
Error type. Useful in our code for mocking these error types.

Add the `InternalErrorCodeIs` to these errors as well to simplify checking the internal codes when
working with these types.

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [X] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [X] I have added tests to cover my changes.
- [X] All new and existing tests passed.
- [X] This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/



Patch:
diff --git a/.changelog/1047.txt b/.changelog/1047.txt
new file mode 100644
index 000000000..3b368ea25
--- /dev/null
+++ b/.changelog/1047.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+errors: add some error type convenience functions for mocking and inspection
+```
diff --git a/errors.go b/errors.go
index da686c357..64c696d6c 100644
--- a/errors.go
+++ b/errors.go
@@ -113,6 +113,10 @@ func (e RequestError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e RequestError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e RequestError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -121,6 +125,12 @@ func (e RequestError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewRequestError(e *Error) RequestError {
+	return RequestError{
+		cloudflareError: e,
+	}
+}
+
 // RatelimitError is for HTTP 429s where the service is telling the client to
 // slow down.
 type RatelimitError struct {
@@ -143,6 +153,10 @@ func (e RatelimitError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e RatelimitError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e RatelimitError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -151,6 +165,12 @@ func (e RatelimitError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewRatelimitError(e *Error) RatelimitError {
+	return RatelimitError{
+		cloudflareError: e,
+	}
+}
+
 // ServiceError is a handler for 5xx errors returned to the client.
 type ServiceError struct {
 	cloudflareError *Error
@@ -172,6 +192,10 @@ func (e ServiceError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e ServiceError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e ServiceError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -180,6 +204,12 @@ func (e ServiceError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewServiceError(e *Error) ServiceError {
+	return ServiceError{
+		cloudflareError: e,
+	}
+}
+
 // AuthenticationError is for HTTP 401 responses.
 type AuthenticationError struct {
 	cloudflareError *Error
@@ -201,6 +231,10 @@ func (e AuthenticationError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e AuthenticationError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e AuthenticationError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -209,6 +243,12 @@ func (e AuthenticationError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewAuthenticationError(e *Error) AuthenticationError {
+	return AuthenticationError{
+		cloudflareError: e,
+	}
+}
+
 // AuthorizationError is for HTTP 403 responses.
 type AuthorizationError struct {
 	cloudflareError *Error
@@ -230,6 +270,10 @@ func (e AuthorizationError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e AuthorizationError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e AuthorizationError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -238,6 +282,12 @@ func (e AuthorizationError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewAuthorizationError(e *Error) AuthorizationError {
+	return AuthorizationError{
+		cloudflareError: e,
+	}
+}
+
 // NotFoundError is for HTTP 404 responses.
 type NotFoundError struct {
 	cloudflareError *Error
@@ -259,6 +309,10 @@ func (e NotFoundError) ErrorMessages() []string {
 	return e.cloudflareError.ErrorMessages
 }
 
+func (e NotFoundError) InternalErrorCodeIs(code int) bool {
+	return e.cloudflareError.InternalErrorCodeIs(code)
+}
+
 func (e NotFoundError) RayID() string {
 	return e.cloudflareError.RayID
 }
@@ -267,6 +321,12 @@ func (e NotFoundError) Type() ErrorType {
 	return e.cloudflareError.Type
 }
 
+func NewNotFoundError(e *Error) NotFoundError {
+	return NotFoundError{
+		cloudflareError: e,
+	}
+}
+
 // ClientError returns a boolean whether or not the raised error was caused by
 // something client side.
 func (e *Error) ClientError() bool {


Test patch:
diff --git a/errors_external_test.go b/errors_external_test.go
new file mode 100644
index 000000000..c9874106c
--- /dev/null
+++ b/errors_external_test.go
@@ -0,0 +1,28 @@
+package cloudflare_test
+
+import (
+	"testing"
+
+	cloudflare "github.com/cloudflare/cloudflare-go"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestError_CreateErrors(t *testing.T) {
+	baseErr := &cloudflare.Error{
+		StatusCode: 400,
+		ErrorCodes: []int{10000},
+	}
+
+	requestErr := cloudflare.NewRequestError(baseErr)
+	assert.True(t, requestErr.InternalErrorCodeIs(10000))
+	limitError := cloudflare.NewRatelimitError(baseErr)
+	assert.True(t, limitError.InternalErrorCodeIs(10000))
+	svcErr := cloudflare.NewServiceError(baseErr)
+	assert.True(t, svcErr.InternalErrorCodeIs(10000))
+	authErr := cloudflare.NewAuthenticationError(baseErr)
+	assert.True(t, authErr.InternalErrorCodeIs(10000))
+	authzErr := cloudflare.NewAuthorizationError(baseErr)
+	assert.True(t, authzErr.InternalErrorCodeIs(10000))
+	notFoundErr := cloudflare.NewNotFoundError(baseErr)
+	assert.True(t, notFoundErr.InternalErrorCodeIs(10000))
+}