errors: use cpuguy83/strongerrors
Signed-off-by: Paulo Pires <pjpires@gmail.com>
This commit is contained in:
49
errors/errors.go
Normal file
49
errors/errors.go
Normal 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
73
errors/errors_test.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
pkgerrors "github.com/pkg/errors"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
@@ -33,6 +32,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
|
|
||||||
|
vkerrors "github.com/virtual-kubelet/virtual-kubelet/errors"
|
||||||
"github.com/virtual-kubelet/virtual-kubelet/log"
|
"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.
|
// Wait for the caches to be synced before starting workers.
|
||||||
if ok := cache.WaitForCacheSync(ctx.Done(), pc.podsInformer.Informer().HasSynced); !ok {
|
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.
|
// 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 {
|
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.
|
// 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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
// Run the syncHandler, passing it the namespace/name string of the Pod resource to be synced.
|
// 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.
|
// We've exceeded the maximum retries, so we must forget the key.
|
||||||
pc.workqueue.Forget(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.
|
// Finally, if no error occurs we Forget this item so it does not get queued again until another change happens.
|
||||||
pc.workqueue.Forget(obj)
|
pc.workqueue.Forget(obj)
|
||||||
@@ -196,7 +196,7 @@ func (pc *PodController) syncHandler(key string) error {
|
|||||||
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Log the error but do not requeue the key as it is invalid.
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ func (pc *PodController) syncHandler(key string) error {
|
|||||||
if !errors.IsNotFound(err) {
|
if !errors.IsNotFound(err) {
|
||||||
// We've failed to fetch the pod from the lister, but the error is not a 404.
|
// 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.
|
// 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.
|
// 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.
|
// 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 {
|
if pod.DeletionTimestamp != nil {
|
||||||
// Delete the pod.
|
// Delete the pod.
|
||||||
if err := pc.server.deletePod(ctx, pod); err != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ func (pc *PodController) syncPodInProvider(ctx context.Context, pod *corev1.Pod)
|
|||||||
}
|
}
|
||||||
// Create the pod in the provider.
|
// Create the pod in the provider.
|
||||||
if err := pc.server.createPod(ctx, pod); err != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ func (pc *PodController) deletePodInProvider(ctx context.Context, namespace, nam
|
|||||||
|
|
||||||
// Delete the pod.
|
// Delete the pod.
|
||||||
if err := pc.server.deletePod(ctx, pod); err != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ func (pc *PodController) deleteDanglingPods(ctx context.Context) error {
|
|||||||
// Grab the list of pods known to the provider.
|
// Grab the list of pods known to the provider.
|
||||||
pps, err := pc.server.provider.GetPods(ctx)
|
pps, err := pc.server.provider.GetPods(ctx)
|
||||||
if err != nil {
|
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.
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
// For some reason we couldn't fetch the pod from the lister, so we propagate the error.
|
// 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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user