Skip to content

Commit

Permalink
Merge pull request #209 from gdbranco/feat/ocm-10939
Browse files Browse the repository at this point in the history
OCM-10939 | feat: include timestamp to error
  • Loading branch information
gdbranco authored Sep 9, 2024
2 parents 9a8e01b + e42e002 commit 30081e9
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
This document describes the relevant changes between releases of the
API metamodel.

## 0.0.61 Sep 06 2024

- Add timestamp to error generator

## 0.0.60 Apr 03 2024

- Add capability of list resource with a scalar items.
Expand Down
47 changes: 47 additions & 0 deletions pkg/generators/golang/errors_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
g.buffer.Import("fmt", "")
g.buffer.Import("io", "")
g.buffer.Import("strings", "")
g.buffer.Import("time", "")
g.buffer.Import("github.com/golang/glog", "")
g.buffer.Import("github.com/openshift-online/ocm-api-metamodel/pkg/runtime", "")
g.buffer.Import(g.packages.HelpersImport(), "")
Expand All @@ -195,6 +196,7 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
reason string
details interface{}
operationID string
timestamp *time.Time
}
// Error represents errors.
Expand All @@ -207,6 +209,7 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
reason string
details interface{}
operationID string
timestamp *time.Time
}
// NewError creates a new builder that can then be used to create error objects.
Expand Down Expand Up @@ -263,6 +266,13 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
return b
}
// Timestamp sets the moment when it happened.
func (b *ErrorBuilder) Timestamp(value *time.Time) *ErrorBuilder {
b.timestamp = value
b.bitmap_ |= 128
return b
}
// Copy copies the attributes of the given error into this
// builder, discarding any previous values.
func (b *ErrorBuilder) Copy(object *Error) *ErrorBuilder {
Expand All @@ -277,6 +287,7 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
b.reason = object.reason
b.details = object.details
b.operationID = object.operationID
b.timestamp = object.timestamp
return b
}
Expand All @@ -290,6 +301,7 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
reason: b.reason,
details: b.details,
operationID: b.operationID,
timestamp: b.timestamp,
bitmap_: b.bitmap_,
}
return
Expand Down Expand Up @@ -429,7 +441,26 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
return
}
// Timestamp sets the moment when it happened
func (e *Error) Timestamp() *time.Time {
if e != nil && e.bitmap_&128 != 0 {
return e.timestamp
}
return nil
}
// GetTimestamp returns the timestamp of the error and a flag
// indicating if the timestamp have a value.
func (e *Error) GetTimestamp() (value *time.Time, ok bool) {
ok = e != nil && e.bitmap_&128 != 0
if ok {
value = e.timestamp
}
return
}
// Error is the implementation of the error interface.
// Details are intentionally left out as there is no guarantee of their type
func (e *Error) Error() string {
chunks := make([]string, 0, 3)
if e.bitmap_&1 != 0 {
Expand All @@ -441,6 +472,9 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
if e.bitmap_&8 != 0 {
chunks = append(chunks, fmt.Sprintf("code is '%s'", e.code))
}
if e.bitmap_&128 != 0 {
chunks = append(chunks, fmt.Sprintf("at '%v'", e.timestamp.Format(time.RFC3339)))
}
if e.bitmap_&32 != 0 {
chunks = append(chunks, fmt.Sprintf("operation identifier is '%s'", e.operationID))
}
Expand Down Expand Up @@ -521,6 +555,14 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
case "details":
object.details = iterator.ReadAny().GetInterface()
object.bitmap_ |= 64
case "timestamp":
text := iterator.ReadString()
value, err := time.Parse(time.RFC3339, text)
if err != nil {
iterator.ReportError("", err.Error())
}
object.timestamp = &value
object.bitmap_ |= 128
default:
iterator.ReadAny()
}
Expand Down Expand Up @@ -578,6 +620,11 @@ func (g *ErrorsGenerator) generateCommonErrors() error {
stream.WriteObjectField("details")
stream.WriteVal(e.details)
}
if e.bitmap_&128 != 0 {
stream.WriteMore()
stream.WriteObjectField("timestamp")
stream.WriteVal(e.timestamp)
}
stream.WriteObjectEnd()
}
Expand Down
35 changes: 35 additions & 0 deletions tests/go/marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package tests

import (
"bytes"
"fmt"
"time"

. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -172,6 +173,38 @@ var _ = Describe("Marshal", func() {
})

It("Can write an error", func() {
now := time.Now().UTC()
object, err := errors.NewError().
ID("401").
HREF("/api/clusters_mgmt/v1/errors/401").
Code("CLUSTERS-MGMT-401").
Reason("My reason").
OperationID("456").
Details(map[string]interface{}{
"kind": "cluster error"}).
Timestamp(&now).
Build()
Expect(err).ToNot(HaveOccurred())
buffer := new(bytes.Buffer)
err = errors.MarshalError(object, buffer)
Expect(err).ToNot(HaveOccurred())
Expect(buffer).To(MatchJSON(fmt.Sprintf(`{
"kind": "Error",
"id": "401",
"href": "/api/clusters_mgmt/v1/errors/401",
"code": "CLUSTERS-MGMT-401",
"reason": "My reason",
"operation_id": "456",
"details": {"kind" : "cluster error"},
"timestamp": "%v"
}`, now.Format(time.RFC3339Nano))))
Expect(object.Error()).To(Equal(
fmt.Sprintf(
"identifier is '401', code is 'CLUSTERS-MGMT-401', at '%v' and operation identifier is '456': My reason",
now.Format(time.RFC3339))))
})

It("Can write an error without timestamp", func() {
object, err := errors.NewError().
ID("401").
HREF("/api/clusters_mgmt/v1/errors/401").
Expand All @@ -194,6 +227,8 @@ var _ = Describe("Marshal", func() {
"operation_id": "456",
"details": {"kind" : "cluster error"}
}`))
Expect(object.Error()).To(Equal(
"identifier is '401', code is 'CLUSTERS-MGMT-401' and operation identifier is '456': My reason"))
})

It("Can write empty list of booleans", func() {
Expand Down

0 comments on commit 30081e9

Please sign in to comment.