-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Propagate bacerrors over nclprotocol (#4774)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced JSON serialization and deserialization for error handling. - Added standardized error handling mechanisms using the `bacerrors` package. - Implemented new error reporting functions for connection management. - **Bug Fixes** - Enhanced error handling logic in various components, improving robustness and clarity. - **Tests** - Added comprehensive unit tests for JSON marshalling and unmarshalling of error structures. - **Chores** - Updated import statements across multiple files to include the `bacerrors` package. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
Showing
10 changed files
with
223 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package bacerrors | ||
|
||
import ( | ||
"encoding/json" | ||
) | ||
|
||
// JSONError is a struct used for JSON serialization of errorImpl | ||
type JSONError struct { | ||
Cause string `json:"Cause"` | ||
Hint string `json:"Hint"` | ||
Retryable bool `json:"Retryable"` | ||
FailsExecution bool `json:"FailsExecution"` | ||
Component string `json:"Component"` | ||
HTTPStatusCode int `json:"HTTPStatusCode"` | ||
Details map[string]string `json:"Details"` | ||
Code ErrorCode `json:"Code"` | ||
} | ||
|
||
// MarshalJSON implements the json.Marshaler interface | ||
func (e *errorImpl) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(&JSONError{ | ||
Cause: e.cause, | ||
Hint: e.hint, | ||
Retryable: e.retryable, | ||
FailsExecution: e.failsExecution, | ||
Component: e.component, | ||
HTTPStatusCode: e.httpStatusCode, | ||
Details: e.details, | ||
Code: e.code, | ||
}) | ||
} | ||
|
||
// UnmarshalJSON implements the json.Unmarshaler interface | ||
func (e *errorImpl) UnmarshalJSON(data []byte) error { | ||
var je JSONError | ||
if err := json.Unmarshal(data, &je); err != nil { | ||
return err | ||
} | ||
|
||
e.cause = je.Cause | ||
e.hint = je.Hint | ||
e.retryable = je.Retryable | ||
e.failsExecution = je.FailsExecution | ||
e.component = je.Component | ||
e.httpStatusCode = je.HTTPStatusCode | ||
e.details = je.Details | ||
e.code = je.Code | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
//go:build unit || !integration | ||
|
||
package bacerrors | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestErrorJSONMarshalling(t *testing.T) { | ||
// Create an error with all fields populated | ||
originalErr := &errorImpl{ | ||
cause: "test error", | ||
hint: "try this instead", | ||
retryable: true, | ||
failsExecution: true, | ||
component: "TestComponent", | ||
httpStatusCode: 404, | ||
details: map[string]string{ | ||
"key1": "value1", | ||
"key2": "value2", | ||
}, | ||
code: NotFoundError, | ||
} | ||
|
||
// Marshal to JSON | ||
jsonData, err := json.Marshal(originalErr) | ||
require.NoError(t, err, "Failed to marshal error to JSON") | ||
|
||
// Unmarshal back to a new error | ||
var unmarshaled errorImpl | ||
err = json.Unmarshal(jsonData, &unmarshaled) | ||
require.NoError(t, err, "Failed to unmarshal JSON to error") | ||
|
||
// Verify all fields match | ||
assert.Equal(t, originalErr.cause, unmarshaled.cause, "Cause field mismatch") | ||
assert.Equal(t, originalErr.hint, unmarshaled.hint, "Hint field mismatch") | ||
assert.Equal(t, originalErr.retryable, unmarshaled.retryable, "Retryable field mismatch") | ||
assert.Equal(t, originalErr.failsExecution, unmarshaled.failsExecution, "FailsExecution field mismatch") | ||
assert.Equal(t, originalErr.component, unmarshaled.component, "Component field mismatch") | ||
assert.Equal(t, originalErr.httpStatusCode, unmarshaled.httpStatusCode, "HTTPStatusCode field mismatch") | ||
assert.Equal(t, originalErr.code, unmarshaled.code, "Code field mismatch") | ||
assert.Equal(t, originalErr.details, unmarshaled.details, "Details field mismatch") | ||
} | ||
|
||
func TestErrorJSONMarshallingEmpty(t *testing.T) { | ||
// Test with minimal fields | ||
originalErr := &errorImpl{ | ||
cause: "minimal error", | ||
} | ||
|
||
// Marshal to JSON | ||
jsonData, err := json.Marshal(originalErr) | ||
require.NoError(t, err, "Failed to marshal minimal error to JSON") | ||
|
||
// Unmarshal back to a new error | ||
var unmarshaled errorImpl | ||
err = json.Unmarshal(jsonData, &unmarshaled) | ||
require.NoError(t, err, "Failed to unmarshal JSON to minimal error") | ||
|
||
// Verify fields | ||
assert.Equal(t, originalErr.cause, unmarshaled.cause, "Cause field mismatch") | ||
assert.Empty(t, unmarshaled.hint, "Hint should be empty") | ||
assert.False(t, unmarshaled.retryable, "Retryable should be false") | ||
assert.False(t, unmarshaled.failsExecution, "FailsExecution should be false") | ||
assert.Empty(t, unmarshaled.component, "Component should be empty") | ||
assert.Zero(t, unmarshaled.httpStatusCode, "HTTPStatusCode should be zero") | ||
assert.Nil(t, unmarshaled.details, "Details should be nil") | ||
assert.Zero(t, unmarshaled.code, "Code should be zero value") | ||
} | ||
|
||
func TestErrorJSONMarshallingInvalid(t *testing.T) { | ||
// Test unmarshalling invalid JSON | ||
invalidJSON := []byte(`{"Cause": "test", "Retryable": "invalid"}`) | ||
var unmarshaled errorImpl | ||
err := json.Unmarshal(invalidJSON, &unmarshaled) | ||
assert.Error(t, err, "Should fail to unmarshal invalid JSON") | ||
} | ||
|
||
func TestErrorJSONFieldVisibility(t *testing.T) { | ||
originalErr := &errorImpl{ | ||
cause: "test error", | ||
hint: "test hint", | ||
retryable: true, | ||
failsExecution: true, | ||
component: "TestComponent", | ||
httpStatusCode: 404, | ||
details: map[string]string{ | ||
"key": "value", | ||
}, | ||
code: NotFoundError, | ||
// These fields should not be marshalled | ||
wrappedErr: nil, | ||
wrappingMsg: "should not appear", | ||
stack: nil, | ||
} | ||
|
||
// Marshal to JSON | ||
jsonData, err := json.Marshal(originalErr) | ||
require.NoError(t, err, "Failed to marshal error to JSON") | ||
|
||
// Convert to map to check field presence | ||
var result map[string]interface{} | ||
err = json.Unmarshal(jsonData, &result) | ||
require.NoError(t, err, "Failed to unmarshal JSON to map") | ||
|
||
// Check that internal fields are not exposed | ||
assert.NotContains(t, result, "wrappedErr", "wrappedErr should not be in JSON") | ||
assert.NotContains(t, result, "wrappingMsg", "wrappingMsg should not be in JSON") | ||
assert.NotContains(t, result, "stack", "stack should not be in JSON") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.