Skip to content

Commit cebed7e

Browse files
authored
chore: wrap errors (#732)
* chore: wrap errors Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * report list result along with error Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fixes Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
1 parent 89c110b commit cebed7e

File tree

17 files changed

+175
-123
lines changed

17 files changed

+175
-123
lines changed

.golangci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ linters:
1313
- unparam
1414
- usestdlibvars
1515
- whitespace
16+
- wrapcheck
1617
settings:
1718
gocritic:
1819
disabled-checks:

agent/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (s *settings) parseManifests() ([]*unstructured.Unstructured, string, error
6464
cmd.Dir = s.repoPath
6565
revision, err := cmd.CombinedOutput()
6666
if err != nil {
67-
return nil, "", err
67+
return nil, "", fmt.Errorf("failed to determine git revision: %w", err)
6868
}
6969
var res []*unstructured.Unstructured
7070
for i := range s.paths {
@@ -80,7 +80,7 @@ func (s *settings) parseManifests() ([]*unstructured.Unstructured, string, error
8080
}
8181
data, err := os.ReadFile(path)
8282
if err != nil {
83-
return err
83+
return fmt.Errorf("failed to read file %s: %w", path, err)
8484
}
8585
items, err := kube.SplitYAML(data)
8686
if err != nil {
@@ -89,7 +89,7 @@ func (s *settings) parseManifests() ([]*unstructured.Unstructured, string, error
8989
res = append(res, items...)
9090
return nil
9191
}); err != nil {
92-
return nil, "", err
92+
return nil, "", fmt.Errorf("failed to parse %s: %w", s.paths[i], err)
9393
}
9494
}
9595
for i := range res {

pkg/cache/cluster.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,15 @@ func (c *clusterCache) stopWatching(gk schema.GroupKind, ns string) {
526526
func (c *clusterCache) startMissingWatches() error {
527527
apis, err := c.kubectl.GetAPIResources(c.config, true, c.settings.ResourcesFilter)
528528
if err != nil {
529-
return err
529+
return fmt.Errorf("failed to get APIResources: %w", err)
530530
}
531531
client, err := c.kubectl.NewDynamicClient(c.config)
532532
if err != nil {
533-
return err
533+
return fmt.Errorf("failed to create client: %w", err)
534534
}
535535
clientset, err := kubernetes.NewForConfig(c.config)
536536
if err != nil {
537-
return err
537+
return fmt.Errorf("failed to create clientset: %w", err)
538538
}
539539
namespacedResources := make(map[schema.GroupKind]bool)
540540
for i := range apis {
@@ -584,7 +584,7 @@ func runSynced(lock sync.Locker, action func() error) error {
584584
// The callback should not wait on any locks that may be held by other callers.
585585
func (c *clusterCache) listResources(ctx context.Context, resClient dynamic.ResourceInterface, callback func(*pager.ListPager) error) (string, error) {
586586
if err := c.listSemaphore.Acquire(ctx, 1); err != nil {
587-
return "", err
587+
return "", fmt.Errorf("failed to acquire list semaphore: %w", err)
588588
}
589589
defer c.listSemaphore.Release(1)
590590

@@ -610,12 +610,16 @@ func (c *clusterCache) listResources(ctx context.Context, resClient dynamic.Reso
610610
retryCount++
611611
c.log.Info(fmt.Sprintf("Error while listing resources: %v (try %d/%d)", ierr, retryCount, c.listRetryLimit))
612612
}
613+
//nolint:wrapcheck // wrap outside the retry
613614
return ierr
614615
}
615616
resourceVersion = res.GetResourceVersion()
616617
return nil
617618
})
618-
return res, err
619+
if err != nil {
620+
return res, fmt.Errorf("failed to list resources: %w", err)
621+
}
622+
return res, nil
619623
})
620624
listPager.PageBufferSize = c.listPageBufferSize
621625
listPager.PageSize = c.listPageSize
@@ -672,11 +676,12 @@ func (c *clusterCache) watchEvents(ctx context.Context, api kube.APIResourceInfo
672676
if apierrors.IsNotFound(err) {
673677
c.stopWatching(api.GroupKind, ns)
674678
}
679+
//nolint:wrapcheck // wrap outside the retry
675680
return res, err
676681
},
677682
})
678683
if err != nil {
679-
return err
684+
return fmt.Errorf("failed to create resource watcher: %w", err)
680685
}
681686

682687
defer func() {
@@ -826,7 +831,7 @@ func (c *clusterCache) checkPermission(ctx context.Context, reviewInterface auth
826831
case len(c.namespaces) == 0 || (!api.Meta.Namespaced && c.clusterResources):
827832
resp, err := reviewInterface.Create(ctx, sar, metav1.CreateOptions{})
828833
if err != nil {
829-
return false, err
834+
return false, fmt.Errorf("failed to create self subject access review: %w", err)
830835
}
831836
if resp != nil && resp.Status.Allowed {
832837
return true, nil
@@ -839,7 +844,7 @@ func (c *clusterCache) checkPermission(ctx context.Context, reviewInterface auth
839844
sar.Spec.ResourceAttributes.Namespace = ns
840845
resp, err := reviewInterface.Create(ctx, sar, metav1.CreateOptions{})
841846
if err != nil {
842-
return false, err
847+
return false, fmt.Errorf("failed to create self subject access review: %w", err)
843848
}
844849
if resp != nil && resp.Status.Allowed {
845850
return true, nil
@@ -883,12 +888,12 @@ func (c *clusterCache) sync() error {
883888
config := c.config
884889
version, err := c.kubectl.GetServerVersion(config)
885890
if err != nil {
886-
return err
891+
return fmt.Errorf("failed to get server version: %w", err)
887892
}
888893
c.serverVersion = version
889894
apiResources, err := c.kubectl.GetAPIResources(config, false, NewNoopSettings())
890895
if err != nil {
891-
return err
896+
return fmt.Errorf("failed to get api resources: %w", err)
892897
}
893898
c.apiResources = apiResources
894899

@@ -905,15 +910,15 @@ func (c *clusterCache) sync() error {
905910

906911
apis, err := c.kubectl.GetAPIResources(c.config, true, c.settings.ResourcesFilter)
907912
if err != nil {
908-
return err
913+
return fmt.Errorf("failed to get api resources: %w", err)
909914
}
910915
client, err := c.kubectl.NewDynamicClient(c.config)
911916
if err != nil {
912-
return err
917+
return fmt.Errorf("failed to create client: %w", err)
913918
}
914919
clientset, err := kubernetes.NewForConfig(config)
915920
if err != nil {
916-
return err
921+
return fmt.Errorf("failed to create clientset: %w", err)
917922
}
918923

919924
if c.batchEventsProcessing {
@@ -1251,7 +1256,7 @@ func (c *clusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructure
12511256
if apierrors.IsNotFound(err) {
12521257
return nil
12531258
}
1254-
return err
1259+
return fmt.Errorf("unexpected error getting managed object: %w", err)
12551260
}
12561261
}
12571262
} else if _, watched := c.apisMeta[key.GroupKind()]; !watched {
@@ -1261,7 +1266,7 @@ func (c *clusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructure
12611266
if apierrors.IsNotFound(err) {
12621267
return nil
12631268
}
1264-
return err
1269+
return fmt.Errorf("unexpected error getting managed object: %w", err)
12651270
}
12661271
}
12671272
}
@@ -1276,7 +1281,7 @@ func (c *clusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructure
12761281
if apierrors.IsNotFound(err) {
12771282
return nil
12781283
}
1279-
return err
1284+
return fmt.Errorf("unexpected error getting managed object: %w", err)
12801285
}
12811286
} else {
12821287
managedObj = converted
@@ -1288,7 +1293,7 @@ func (c *clusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructure
12881293
return nil
12891294
})
12901295
if err != nil {
1291-
return nil, err
1296+
return nil, fmt.Errorf("failed to get managed objects: %w", err)
12921297
}
12931298

12941299
return managedObjs, nil

pkg/cache/references.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ func isStatefulSetChild(un *unstructured.Unstructured) (func(kube.ResourceKey) b
6363
sts := appsv1.StatefulSet{}
6464
data, err := json.Marshal(un)
6565
if err != nil {
66-
return nil, err
66+
return nil, fmt.Errorf("failed to marshal unstructured object: %w", err)
6767
}
6868
err = json.Unmarshal(data, &sts)
6969
if err != nil {
70-
return nil, err
70+
return nil, fmt.Errorf("failed to unmarshal statefulset: %w", err)
7171
}
7272

7373
templates := sts.Spec.VolumeClaimTemplates

pkg/diff/diff.go

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,15 @@ func apply(tvConfig, tvLive *typed.TypedValue, p *SMDParams) (*typed.TypedValue,
421421
if err != nil {
422422
return nil, fmt.Errorf("error while running updater.Apply: %w", err)
423423
}
424-
return mergedLive, err
424+
return mergedLive, nil
425425
}
426426

427427
func buildManagerInfoForApply(manager string) (string, error) {
428428
managerInfo := metav1.ManagedFieldsEntry{
429429
Manager: manager,
430430
Operation: metav1.ManagedFieldsOperationApply,
431431
}
432+
//nolint:wrapcheck // trivial function, wrapped nicely by the caller
432433
return fieldmanager.BuildManagerIdentifier(&managerInfo)
433434
}
434435

@@ -489,13 +490,13 @@ func handleResourceCreateOrDeleteDiff(config, live *unstructured.Unstructured) (
489490
if live != nil {
490491
liveData, err := json.Marshal(live)
491492
if err != nil {
492-
return nil, err
493+
return nil, fmt.Errorf("error marshaling live resource: %w", err)
493494
}
494495
return &DiffResult{Modified: false, NormalizedLive: liveData, PredictedLive: []byte("null")}, nil
495496
} else if config != nil {
496497
predictedLiveData, err := json.Marshal(config.Object)
497498
if err != nil {
498-
return nil, err
499+
return nil, fmt.Errorf("error marshaling config resource: %w", err)
499500
}
500501
return &DiffResult{Modified: true, NormalizedLive: []byte("null"), PredictedLive: predictedLiveData}, nil
501502
}
@@ -539,7 +540,7 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() (
539540
// Apply the patchBytes patch against liveBytes, using predictedLive to indicate the k8s data type
540541
predictedLiveBytes, err := strategicpatch.StrategicMergePatch(liveBytes, patchBytes, predictedLive)
541542
if err != nil {
542-
return nil, nil, err
543+
return nil, nil, fmt.Errorf("failed to construct strategic merge patch: %w", err)
543544
}
544545

545546
// Unmarshal predictedLiveBytes into predictedLive; note that this will discard JSON fields in predictedLiveBytes
@@ -562,7 +563,7 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() (
562563
// to its k8s resource type (eg the JSON may contain those invalid fields that we do not wish to discard).
563564
predictedLiveBytes, err = strategicpatch.StrategicMergePatch(predictedLiveBytes, patch, predictedLive.DeepCopyObject())
564565
if err != nil {
565-
return nil, nil, err
566+
return nil, nil, fmt.Errorf("failed to construct strategic merge patch for predicted state: %w", err)
566567
}
567568

568569
// 3) Unmarshall into a map[string]any, then back into byte[], to ensure the fields
@@ -571,11 +572,11 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() (
571572
var result map[string]any
572573
err = json.Unmarshal([]byte(predictedLiveBytes), &result)
573574
if err != nil {
574-
return nil, nil, err
575+
return nil, nil, fmt.Errorf("failed to unmarshal strategic merge patch for predicted state: %w", err)
575576
}
576577
predictedLiveBytes, err = json.Marshal(result)
577578
if err != nil {
578-
return nil, nil, err
579+
return nil, nil, fmt.Errorf("failed to marshal strategic merge patch for predicted state: %w", err)
579580
}
580581
}
581582

@@ -595,18 +596,18 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() (
595596
}
596597
liveBytes, err = strategicpatch.StrategicMergePatch(liveBytes, patch, live.DeepCopyObject())
597598
if err != nil {
598-
return nil, nil, err
599+
return nil, nil, fmt.Errorf("failed to construct strategic merge patch for live state: %w", err)
599600
}
600601

601602
// Ensure the fields are sorted in a consistent order (as above)
602603
var result map[string]any
603604
err = json.Unmarshal([]byte(liveBytes), &result)
604605
if err != nil {
605-
return nil, nil, err
606+
return nil, nil, fmt.Errorf("failed to unmarshal strategic merge patch for live state: %w", err)
606607
}
607608
liveBytes, err = json.Marshal(result)
608609
if err != nil {
609-
return nil, nil, err
610+
return nil, nil, fmt.Errorf("failed to marshal strategic merge patch for live state: %w", err)
610611
}
611612
}
612613

@@ -662,7 +663,7 @@ func ThreeWayDiff(orig, config, live *unstructured.Unstructured) (*DiffResult, e
662663
// 2. get expected live object by applying the patch against the live object
663664
liveBytes, err := json.Marshal(live)
664665
if err != nil {
665-
return nil, err
666+
return nil, fmt.Errorf("failed to marshal live state: %w", err)
666667
}
667668

668669
var predictedLiveBytes []byte
@@ -677,7 +678,7 @@ func ThreeWayDiff(orig, config, live *unstructured.Unstructured) (*DiffResult, e
677678
// Otherwise, merge patch directly as JSON
678679
predictedLiveBytes, err = jsonpatch.MergePatch(liveBytes, patchBytes)
679680
if err != nil {
680-
return nil, err
681+
return nil, fmt.Errorf("failed to construct merge patch for predicted state: %w", err)
681682
}
682683
}
683684

@@ -733,11 +734,11 @@ func statefulSetWorkaround(orig, live *unstructured.Unstructured) *unstructured.
733734
func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte, func() (runtime.Object, error), error) {
734735
origBytes, err := json.Marshal(orig.Object)
735736
if err != nil {
736-
return nil, nil, err
737+
return nil, nil, fmt.Errorf("failed to marshal original object: %w", err)
737738
}
738739
configBytes, err := json.Marshal(config.Object)
739740
if err != nil {
740-
return nil, nil, err
741+
return nil, nil, fmt.Errorf("failed to marshal config object: %w", err)
741742
}
742743

743744
if versionedObject, err := scheme.Scheme.New(orig.GroupVersionKind()); err == nil {
@@ -748,16 +749,16 @@ func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte,
748749

749750
liveBytes, err := json.Marshal(live.Object)
750751
if err != nil {
751-
return nil, nil, err
752+
return nil, nil, fmt.Errorf("failed to marshal live object: %w", err)
752753
}
753754

754755
lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObject)
755756
if err != nil {
756-
return nil, nil, err
757+
return nil, nil, fmt.Errorf("failed to construct lookup patch: %w", err)
757758
}
758759
patch, err := strategicpatch.CreateThreeWayMergePatch(origBytes, configBytes, liveBytes, lookupPatchMeta, true)
759760
if err != nil {
760-
return nil, nil, err
761+
return nil, nil, fmt.Errorf("failed to construct thre way merge patch: %w", err)
761762
}
762763
newVersionedObject := func() (runtime.Object, error) {
763764
return scheme.Scheme.New(orig.GroupVersionKind())
@@ -770,12 +771,12 @@ func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte,
770771

771772
liveBytes, err := json.Marshal(live.Object)
772773
if err != nil {
773-
return nil, nil, err
774+
return nil, nil, fmt.Errorf("failed to marshal live object: %w", err)
774775
}
775776

776777
patch, err := jsonmergepatch.CreateThreeWayJSONMergePatch(origBytes, configBytes, liveBytes)
777778
if err != nil {
778-
return nil, nil, err
779+
return nil, nil, fmt.Errorf("failed to construct thre way merge patch: %w", err)
779780
}
780781
return patch, nil, nil
781782
}
@@ -989,15 +990,15 @@ func normalizeRole(un *unstructured.Unstructured, o options) {
989990
func CreateTwoWayMergePatch(orig, new, dataStruct any) ([]byte, bool, error) {
990991
origBytes, err := json.Marshal(orig)
991992
if err != nil {
992-
return nil, false, err
993+
return nil, false, fmt.Errorf("failed to marshal orig object: %w", err)
993994
}
994995
newBytes, err := json.Marshal(new)
995996
if err != nil {
996-
return nil, false, err
997+
return nil, false, fmt.Errorf("failed to marshal new object: %w", err)
997998
}
998999
patch, err := strategicpatch.CreateTwoWayMergePatch(origBytes, newBytes, dataStruct)
9991000
if err != nil {
1000-
return nil, false, err
1001+
return nil, false, fmt.Errorf("failed to create two way merge patch: %w", err)
10011002
}
10021003
return patch, string(patch) != "{}", nil
10031004
}

pkg/diff/diff_options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ func NewK8sServerSideDryRunner(kubeApplier KubeApplier) *K8sServerSideDryRunner
6666
// obj and the given manager in dryrun mode. Will return the predicted live state
6767
// json as string.
6868
func (kdr *K8sServerSideDryRunner) Run(ctx context.Context, obj *unstructured.Unstructured, manager string) (string, error) {
69+
//nolint:wrapcheck // trivial function, don't bother wrapping
6970
return kdr.dryrunApplier.ApplyResource(ctx, obj, cmdutil.DryRunServer, false, false, true, manager)
7071
}
7172

0 commit comments

Comments
 (0)