Skip to content

Skip nil data from serialized JSON #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ For a better understanding of the features provided by the package check the doc

# Quick demo

There's an example at `examples/example1/example1.go` that shows how to use the package. Here's the code for the example:
There's an example at `examples/example1/example1.go` that shows how to use the package.

<details><summary>Here's the code for the example:</summary>

```go
package main
Expand Down Expand Up @@ -78,11 +80,11 @@ func open() error {
func main() {
if err := createTransaction("tx_123456"); err != nil {
b, _ := json.MarshalIndent(err, "", " ")
fmt.Println("Error logged as a JSON structure using the JSON.MarshalIndent:")
fmt.Println("Error logged as a JSON structure using the json.MarshalIndent:")
fmt.Printf("%s\n", b)

b, _ = json.Marshal(err)
fmt.Println("\nError logged as a JSON structure using the JSON.Marshal:")
fmt.Println("\nError logged as a JSON structure using the json.Marshal:")
fmt.Printf("%s\n", b)

fmt.Println("\nError logged using the s format specifier:")
Expand All @@ -94,11 +96,13 @@ func main() {
}
```

Here's the execution of the example:
</details>

<details><summary>Here's the execution of the example:</summary>

```
$ go run examples/example1/example1.go
Error logged as a JSON structure using the JSON.MarshalIndent:
$ go run examples/example1/example1.go
Error logged as a JSON structure using the json.MarshalIndent:
[
{
"data": {
Expand Down Expand Up @@ -160,7 +164,7 @@ Error logged as a JSON structure using the JSON.MarshalIndent:
}
]

Error logged as a JSON structure using the JSON.Marshal:
Error logged as a JSON structure using the json.Marshal:
[{"data":{"transactionId":"tx_123456","userId":"67890"},"message":"failed to complete the transaction on bank_123456","stack":["main.createTransaction @ /root/hack/errors/examples/example1/example1.go:13","main.main @ /root/hack/errors/examples/example1/example1.go:52","runtime/internal/atomic.(*Uint32).Load @ /root/go/version/go1.21.0/src/runtime/internal/atomic/types.go:194","runtime.goexit @ /root/go/version/go1.21.0/src/runtime/asm_amd64.s:1651"]},{"data":{"operation":"update","tableName":"transactions"},"message":"failed to update the database","stack":["main.updateDatabase @ /root/hack/errors/examples/example1/example1.go:24","main.createTransaction @ /root/hack/errors/examples/example1/example1.go:12","main.main @ /root/hack/errors/examples/example1/example1.go:52","runtime/internal/atomic.(*Uint32).Load @ /root/go/version/go1.21.0/src/runtime/internal/atomic/types.go:194","runtime.goexit @ /root/go/version/go1.21.0/src/runtime/asm_amd64.s:1651"]},{"data":{"server":"db-server-01","timeoutSeconds":30},"message":"connection timeout","stack":["main.createConnection @ /root/hack/errors/examples/example1/example1.go:35","main.updateDatabase @ /root/hack/errors/examples/example1/example1.go:23","main.createTransaction @ /root/hack/errors/examples/example1/example1.go:12","main.main @ /root/hack/errors/examples/example1/example1.go:52","runtime/internal/atomic.(*Uint32).Load @ /root/go/version/go1.21.0/src/runtime/internal/atomic/types.go:194","runtime.goexit @ /root/go/version/go1.21.0/src/runtime/asm_amd64.s:1651"]},{"data":{"network":"internal","severity":"high"},"message":"network instability detected","stack":["main.open @ /root/hack/errors/examples/example1/example1.go:45","main.createConnection @ /root/hack/errors/examples/example1/example1.go:34","main.updateDatabase @ /root/hack/errors/examples/example1/example1.go:23","main.createTransaction @ /root/hack/errors/examples/example1/example1.go:12","main.main @ /root/hack/errors/examples/example1/example1.go:52","runtime/internal/atomic.(*Uint32).Load @ /root/go/version/go1.21.0/src/runtime/internal/atomic/types.go:194","runtime.goexit @ /root/go/version/go1.21.0/src/runtime/asm_amd64.s:1651"]}]

Error logged using the s format specifier:
Expand All @@ -170,8 +174,8 @@ Error logged using the +v format specifier:
message:
"failed to complete the transaction on bank_123456"
data:
transactionId: tx_123456
userId: 67890
transactionId: tx_123456
stack:
main.createTransaction @ /root/hack/errors/examples/example1/example1.go:13
main.main @ /root/hack/errors/examples/example1/example1.go:52
Expand Down Expand Up @@ -216,4 +220,6 @@ cause:
main.main @ /root/hack/errors/examples/example1/example1.go:52
runtime/internal/atomic.(*Uint32).Load @ /root/go/version/go1.21.0/src/runtime/internal/atomic/types.go:194
runtime.goexit @ /root/go/version/go1.21.0/src/runtime/asm_amd64.s:1651
```
```

</details>
4 changes: 3 additions & 1 deletion convertion.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ func toMapAndCause(err error) (map[string]any, error) {

if e, ok := err.(*Err); ok {
errMap["message"] = e.Message
errMap["data"] = e.Data
if e.Data != nil {
errMap["data"] = e.Data
}
errMap["stack"] = e.Stack
errCause = e.Cause
} else {
Expand Down
32 changes: 31 additions & 1 deletion error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ func TestJSONMarshaling(t *testing.T) {
t.Run("when marshaling a nested chain of errors.Err errors, should marshal the full chain", func(t *testing.T) {
err1 := New("context timeout")
err2 := Wrap(err1, "failed to connect to the database")
err3 := Wrap(err2, "failed to start the server")
err3 := Wrapd(err2, Data{
"server": "db-server-01",
}, "failed to start the server")

b, err := json.MarshalIndent(err3, "", " ")
if err != nil {
Expand All @@ -27,17 +29,45 @@ func TestJSONMarshaling(t *testing.T) {
t.Fatalf("unexpected number of errors, got %d, expected %d", len(errs), 3)
}

// testing err3

if fmt.Sprint(errs[0]["message"]) != err3.(*Err).Message {
t.Errorf("unexpected error message, got %q, expected %q", errs[0]["message"], err3.(*Err).Message)
}

dataErr3, ok := errs[0]["data"]
if !ok {
t.Errorf("unexpected data, got undefined key, expected %v", err3.(*Err).Data)
}

b1, err := json.Marshal(dataErr3)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
b2, err := json.Marshal(err3.(*Err).Data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

if string(b1) != string(b2) {
t.Errorf("unexpected data, got %s, expected %s", b1, b2)
}

// testing err2

if fmt.Sprint(errs[1]["message"]) != err2.(*Err).Message {
t.Errorf("unexpected error message, got %q, expected %q", errs[1]["message"], err2.(*Err).Message)
}

// testing err1

if fmt.Sprint(errs[2]["message"]) != err1.(*Err).Message {
t.Errorf("unexpected error message, got %q, expected %q", errs[2]["message"], err1.(*Err).Message)
}

if _, ok := errs[2]["data"]; ok {
t.Errorf("unexpected data, got %v, expected undefined key", errs[0]["data"])
}
})

t.Run("when marshaling a chain of errors.Err and standard errors, should marshal the full chain", func(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions examples/example1/example1.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ func open() error {
func main() {
if err := createTransaction("tx_123456"); err != nil {
b, _ := json.MarshalIndent(err, "", " ")
fmt.Println("Error logged as a JSON structure using the JSON.MarshalIndent:")
fmt.Println("Error logged as a JSON structure using the json.MarshalIndent:")
fmt.Printf("%s\n", b)

b, _ = json.Marshal(err)
fmt.Println("\nError logged as a JSON structure using the JSON.Marshal:")
fmt.Println("\nError logged as a JSON structure using the json.Marshal:")
fmt.Printf("%s\n", b)

fmt.Println("\nError logged using the s format specifier:")
Expand Down
Loading