errors: use cpuguy83/strongerrors

Signed-off-by: Paulo Pires <pjpires@gmail.com>
This commit is contained in:
Paulo Pires
2018-11-29 22:18:15 +00:00
parent 058c683c66
commit f031fc6d6b
3 changed files with 133 additions and 11 deletions

49
errors/errors.go Normal file
View File

@@ -0,0 +1,49 @@
// Copyright © 2017 The virtual-kubelet authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package errors
import (
"fmt"
"github.com/cpuguy83/strongerrors"
)
// DeadlineWithMessage creates a "Deadline" error with the specified message and formatting arguments.
func DeadlineWithMessage(format string, args ...interface{}) error {
return strongerrors.Deadline(fmt.Errorf(format, args...))
}
// Exhausted creates an "Exhausted" error from the specified error.
func Exhausted(err error) error {
return strongerrors.Exhausted(err)
}
// InvalidArgument creates an "InvalidArgument" error from the specified error.
func InvalidArgument(err error) error {
return strongerrors.InvalidArgument(err)
}
// InvalidArgumentWithMessage creates an "InvalidArgument" error with the specified message and formatting arguments.
func InvalidArgumentWithMessage(format string, args ...interface{}) error {
return strongerrors.InvalidArgument(fmt.Errorf(format, args...))
}
// Unknown creates an "Unknown" error from the specified error and optional message and formatting arguments.
func Unknown(err error, args ...interface{}) error {
// If we've been given additional arguments, re-format the error
if len(args) >= 1 {
err = fmt.Errorf("%s: %s", fmt.Sprintf(args[0].(string), args[1:]...), err)
}
return strongerrors.Unknown(err)
}

73
errors/errors_test.go Normal file
View File

@@ -0,0 +1,73 @@
// Copyright © 2017 The virtual-kubelet authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package errors
import (
goerrors "errors"
"testing"
"github.com/cpuguy83/strongerrors"
)
func TestUnknownFromRoot(t *testing.T) {
// Create a root cause.
// This represents an error returned by a function invocation.
err1 := goerrors.New("root cause")
// Create an error of type "Unknown" with err1 as the cause and containing an additional message.
err2 := Unknown(err1)
// Make sure that the resulting error is indeed of type "Unknown".
if !strongerrors.IsUnknown(err2) {
t.Fatal("expected err2 to be of type Unknown")
}
// Make sure that the error's message is equal to the root cause's message.
if err2.Error() != "root cause" {
t.Fatal("expected err2's error message to be equal to the root cause's message")
}
}
func TestUnknownFromRootCauseWithMessage(t *testing.T) {
// Create a root cause.
// This represents an error returned by a function invocation.
err1 := goerrors.New("root cause")
// Create an error of type "Unknown" with err1 as the cause and containing an additional message.
err2 := Unknown(err1, "extra info")
// Make sure that the resulting error is indeed of type "Unknown".
if !strongerrors.IsUnknown(err2) {
t.Fatal("expected err2 to be of type Unknown")
}
// Make sure that the message was adequately formatted.
if err2.Error() != "extra info: root cause" {
t.Fatal("expected err2 to be adequately formatted as a string")
}
}
func TestUnknownFromRootCauseWithMessageAndFormattingParameters(t *testing.T) {
// Create a root cause.
// This represents an error returned by a function invocation.
err1 := goerrors.New("root cause")
// Create an error of type "Unknown" with err1 as the cause and containing an additional message.
err2 := Unknown(err1, "expected %d, got %d", 0, 1)
// Make sure that the resulting error is indeed of type "Unknown".
if !strongerrors.IsUnknown(err2) {
t.Fatal("expected err2 to be of type Unknown")
}
// Make sure that the message was adequately formatted.
if err2.Error() != "expected 0, got 1: root cause" {
t.Fatal("expected err2 to be adequately formatted as a string")
}
}

View File

@@ -20,7 +20,6 @@ import (
"sync"
"time"
pkgerrors "github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/runtime"
@@ -33,6 +32,7 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
vkerrors "github.com/virtual-kubelet/virtual-kubelet/errors"
"github.com/virtual-kubelet/virtual-kubelet/log"
)
@@ -112,7 +112,7 @@ func (pc *PodController) Run(ctx context.Context, threadiness int) error {
// Wait for the caches to be synced before starting workers.
if ok := cache.WaitForCacheSync(ctx.Done(), pc.podsInformer.Informer().HasSynced); !ok {
return pkgerrors.New("failed to wait for caches to sync")
return vkerrors.DeadlineWithMessage("failed to wait for caches to sync")
}
// Perform a reconciliation step that deletes any dangling pods from the provider.
@@ -162,7 +162,7 @@ func (pc *PodController) processNextWorkItem() bool {
if key, ok = obj.(string); !ok {
// As the item in the work queue is actually invalid, we call Forget here else we'd go into a loop of attempting to process a work item that is invalid.
pc.workqueue.Forget(obj)
runtime.HandleError(pkgerrors.Errorf("expected string in work queue but got %#v", obj))
runtime.HandleError(vkerrors.InvalidArgumentWithMessage("expected string in work queue but got %#v", obj))
return nil
}
// Run the syncHandler, passing it the namespace/name string of the Pod resource to be synced.
@@ -175,7 +175,7 @@ func (pc *PodController) processNextWorkItem() bool {
}
// We've exceeded the maximum retries, so we must forget the key.
pc.workqueue.Forget(key)
return pkgerrors.Wrapf(err, "forgetting %q due to maximum retries reached", key)
return vkerrors.Exhausted(err)
}
// Finally, if no error occurs we Forget this item so it does not get queued again until another change happens.
pc.workqueue.Forget(obj)
@@ -196,7 +196,7 @@ func (pc *PodController) syncHandler(key string) error {
namespace, name, err := cache.SplitMetaNamespaceKey(key)
if err != nil {
// Log the error but do not requeue the key as it is invalid.
runtime.HandleError(pkgerrors.Wrapf(err, "invalid resource key: %q", key))
runtime.HandleError(vkerrors.InvalidArgument(err))
return nil
}
@@ -209,7 +209,7 @@ func (pc *PodController) syncHandler(key string) error {
if !errors.IsNotFound(err) {
// We've failed to fetch the pod from the lister, but the error is not a 404.
// Hence, we add the key back to the work queue so we can retry processing it later.
return pkgerrors.Wrapf(err, "failed to fetch pod with key %q from lister", key)
return vkerrors.Unknown(err, "failed to fetch pod with key %q from lister", key)
}
// At this point we know the Pod resource doesn't exist, which most probably means it was deleted.
// Hence, we must delete it from the provider if it still exists there.
@@ -229,7 +229,7 @@ func (pc *PodController) syncPodInProvider(ctx context.Context, pod *corev1.Pod)
if pod.DeletionTimestamp != nil {
// Delete the pod.
if err := pc.server.deletePod(ctx, pod); err != nil {
return pkgerrors.Wrapf(err, "failed to delete pod %q in the provider", key)
return vkerrors.Unknown(err, "failed to delete pod %q in the provider", key)
}
return nil
}
@@ -250,7 +250,7 @@ func (pc *PodController) syncPodInProvider(ctx context.Context, pod *corev1.Pod)
}
// Create the pod in the provider.
if err := pc.server.createPod(ctx, pod); err != nil {
return pkgerrors.Wrapf(err, "failed to create pod %q in the provider", key)
return vkerrors.Unknown(err, "failed to create pod %q in the provider", key)
}
return nil
}
@@ -273,7 +273,7 @@ func (pc *PodController) deletePodInProvider(ctx context.Context, namespace, nam
// Delete the pod.
if err := pc.server.deletePod(ctx, pod); err != nil {
return pkgerrors.Wrapf(err, "failed to delete pod %q in the provider", key)
return vkerrors.Unknown(err, "failed to delete pod %q in the provider", key)
}
return nil
}
@@ -283,7 +283,7 @@ func (pc *PodController) deleteDanglingPods(ctx context.Context) error {
// Grab the list of pods known to the provider.
pps, err := pc.server.provider.GetPods(ctx)
if err != nil {
return pkgerrors.Wrap(err, "failed to fetch the list of pods from the provider")
return vkerrors.Unknown(err, "failed to fetch the list of pods from the provider")
}
// Create a slice to hold the pods we will be deleting from the provider.
@@ -299,7 +299,7 @@ func (pc *PodController) deleteDanglingPods(ctx context.Context) error {
continue
}
// For some reason we couldn't fetch the pod from the lister, so we propagate the error.
return pkgerrors.Wrap(err, "failed to fetch pod from the lister")
return vkerrors.Unknown(err, "failed to fetch pod from the lister")
}
}