Skip to content

Commit c0bae6e

Browse files
Fixes improper usage of log.Error(nil,..) scenarios for EventHandler
1 parent 865f77a commit c0bae6e

File tree

7 files changed

+40
-34
lines changed

7 files changed

+40
-34
lines changed

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,8 @@ lint: lint-custom $(GOLANGCI_LINT) #HELP Run golangci linter.
103103
$(GOLANGCI_LINT) run --build-tags $(GO_BUILD_TAGS) $(GOLANGCI_LINT_ARGS)
104104

105105
.PHONY: custom-linter-build
106-
LINTER_DIR := ./hack/ci/custom-linters/cmd
107106
custom-linter-build: # HELP Build custom linter
108-
cd $(LINTER_DIR) && go build -tags '$(GO_BUILD_TAGS)' -o $(ROOT_DIR)/bin/custom-linter
107+
go build -tags $(GO_BUILD_TAGS) -o ./bin/custom-linter ./hack/ci/custom-linters/cmd
109108

110109
.PHONY: lint-custom #HELP Call custom linter for the project
111110
lint-custom: custom-linter-build

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ require (
2626
github.com/stretchr/testify v1.10.0
2727
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
2828
golang.org/x/sync v0.11.0
29+
golang.org/x/tools v0.29.0
2930
gopkg.in/yaml.v2 v2.4.0
3031
helm.sh/helm/v3 v3.17.0
3132
k8s.io/api v0.32.0
@@ -232,7 +233,6 @@ require (
232233
golang.org/x/term v0.28.0 // indirect
233234
golang.org/x/text v0.21.0 // indirect
234235
golang.org/x/time v0.7.0 // indirect
235-
golang.org/x/tools v0.29.0 // indirect
236236
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
237237
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
238238
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect

hack/ci/custom-linters/analyzers/setuplognilerrorcheck.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package analyzers
22

33
import (
44
"bytes"
5-
"fmt"
65
"go/ast"
76
"go/format"
87
"go/token"
@@ -75,10 +74,9 @@ func runSetupLogNilErrorCheck(pass *analysis.Pass) (interface{}, error) {
7574
pass.Reportf(callExpr.Pos(),
7675
"Incorrect usage of 'logger.Error(nil, ...)'. The first argument must be a non-nil 'error'. "+
7776
"Passing 'nil' results in silent failures, making debugging harder.\n\n"+
78-
"\U0001F41B **What is wrong?**\n"+
79-
fmt.Sprintf(" %s\n\n", sourceLine)+
80-
"\U0001F4A1 **How to solve? Return the error, i.e.:**\n"+
81-
fmt.Sprintf(" logger.Error(%s, %s, \"key\", value)\n\n", suggestedError, suggestedMessage))
77+
"\U0001F41B **What is wrong?**\n %s\n\n"+
78+
"\U0001F4A1 **How to solve? Return the error, i.e.:**\n logger.Error(%s, %s, \"key\", value)\n\n",
79+
sourceLine, suggestedError, suggestedMessage)
8280
}
8381

8482
return true

hack/ci/custom-linters/cmd/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package main
22

33
import (
4-
"github.com/operator-framework/operator-controller/hack/ci/custom-linters/analyzers"
54
"golang.org/x/tools/go/analysis"
65
"golang.org/x/tools/go/analysis/unitchecker"
6+
7+
"github.com/operator-framework/operator-controller/hack/ci/custom-linters/analyzers"
78
)
89

910
// Define the custom Linters implemented in the project

hack/ci/custom-linters/go.mod

Lines changed: 0 additions & 5 deletions
This file was deleted.

hack/ci/custom-linters/go.sum

Lines changed: 0 additions & 8 deletions
This file was deleted.

internal/contentmanager/source/internal/eventhandler.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ limitations under the License.
3838

3939
import (
4040
"context"
41+
"errors"
4142
"fmt"
4243

4344
cgocache "k8s.io/client-go/tools/cache"
@@ -94,8 +95,11 @@ func (e *EventHandler[object, request]) OnAdd(obj interface{}) {
9495
if o, ok := obj.(object); ok {
9596
c.Object = o
9697
} else {
97-
log.Error(nil, "OnAdd missing Object",
98-
"object", obj, "type", fmt.Sprintf("%T", obj))
98+
log.Error(errors.New("failed to cast object"),
99+
"OnAdd missing Object",
100+
"expected_type", fmt.Sprintf("%T", c.Object),
101+
"received_type", fmt.Sprintf("%T", obj),
102+
"object", obj)
99103
return
100104
}
101105

@@ -118,20 +122,27 @@ func (e *EventHandler[object, request]) OnUpdate(oldObj, newObj interface{}) {
118122
if o, ok := oldObj.(object); ok {
119123
u.ObjectOld = o
120124
} else {
121-
log.Error(nil, "OnUpdate missing ObjectOld",
122-
"object", oldObj, "type", fmt.Sprintf("%T", oldObj))
125+
log.Error(errors.New("failed to cast old object"),
126+
"OnUpdate missing ObjectOld",
127+
"object", oldObj,
128+
"expected_type", fmt.Sprintf("%T", u.ObjectOld),
129+
"received_type", fmt.Sprintf("%T", oldObj))
123130
return
124131
}
125132

126133
// Pull Object out of the object
127134
if o, ok := newObj.(object); ok {
128135
u.ObjectNew = o
129136
} else {
130-
log.Error(nil, "OnUpdate missing ObjectNew",
131-
"object", newObj, "type", fmt.Sprintf("%T", newObj))
137+
log.Error(errors.New("failed to cast new object"),
138+
"OnUpdate missing ObjectNew",
139+
"object", newObj,
140+
"expected_type", fmt.Sprintf("%T", u.ObjectNew),
141+
"received_type", fmt.Sprintf("%T", newObj))
132142
return
133143
}
134144

145+
// Run predicates before proceeding
135146
for _, p := range e.predicates {
136147
if !p.Update(u) {
137148
return
@@ -148,18 +159,25 @@ func (e *EventHandler[object, request]) OnUpdate(oldObj, newObj interface{}) {
148159
func (e *EventHandler[object, request]) OnDelete(obj interface{}) {
149160
d := event.TypedDeleteEvent[object]{}
150161

162+
// Handle tombstone events (cache.DeletedFinalStateUnknown)
163+
if obj == nil {
164+
log.Error(errors.New("received nil object"),
165+
"OnDelete received a nil object, ignoring event")
166+
return
167+
}
168+
151169
// Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a
152170
// DeleteFinalStateUnknown struct, so the object needs to be pulled out.
153171
// Copied from sample-controller
154172
// This should never happen if we aren't missing events, which we have concluded that we are not
155173
// and made decisions off of this belief. Maybe this shouldn't be here?
156-
var ok bool
157-
if _, ok = obj.(client.Object); !ok {
174+
if _, ok := obj.(client.Object); !ok {
158175
// If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown
159176
tombstone, ok := obj.(cgocache.DeletedFinalStateUnknown)
160177
if !ok {
161-
log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown",
162-
"type", fmt.Sprintf("%T", obj),
178+
log.Error(errors.New("unexpected object type"),
179+
"Error decoding objects, expected cache.DeletedFinalStateUnknown",
180+
"received_type", fmt.Sprintf("%T", obj),
163181
"object", obj)
164182
return
165183
}
@@ -175,8 +193,11 @@ func (e *EventHandler[object, request]) OnDelete(obj interface{}) {
175193
if o, ok := obj.(object); ok {
176194
d.Object = o
177195
} else {
178-
log.Error(nil, "OnDelete missing Object",
179-
"object", obj, "type", fmt.Sprintf("%T", obj))
196+
log.Error(errors.New("failed to cast object"),
197+
"OnDelete missing Object",
198+
"expected_type", fmt.Sprintf("%T", d.Object),
199+
"received_type", fmt.Sprintf("%T", obj),
200+
"object", obj)
180201
return
181202
}
182203

0 commit comments

Comments
 (0)