Skip to content

Commit

Permalink
Recover panic for controller reconcile and webhook handler
Browse files Browse the repository at this point in the history
Signed-off-by: FillZpp <FillZpp.pub@gmail.com>
  • Loading branch information
FillZpp committed Aug 9, 2021
1 parent c0a5bab commit 3cffa52
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
12 changes: 11 additions & 1 deletion pkg/internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"runtime/debug"
"sync"
"time"

Expand Down Expand Up @@ -295,7 +296,7 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {

// RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the
// resource to be synced.
result, err := c.Do.Reconcile(ctx, req)
result, err := c.doReconcile(ctx, req)
switch {
case err != nil:
c.Queue.AddRateLimited(req)
Expand All @@ -321,6 +322,15 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {
}
}

func (c *Controller) doReconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v [recovered]\n\n%s", r, debug.Stack())
}
}()
return c.Do.Reconcile(ctx, req)
}

// GetLogger returns this controller's logger.
func (c *Controller) GetLogger() logr.Logger {
return c.Log
Expand Down
13 changes: 11 additions & 2 deletions pkg/webhook/admission/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package admission
import (
"context"
"errors"
"fmt"
"net/http"
"runtime/debug"

"github.com/go-logr/logr"
jsonpatch "gomodules.xyz/jsonpatch/v2"
Expand Down Expand Up @@ -142,8 +144,15 @@ func (wh *Webhook) InjectLogger(l logr.Logger) error {
// If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches.
// If the webhook is validating type, it delegates the AdmissionRequest to each handler and
// deny the request if anyone denies.
func (wh *Webhook) Handle(ctx context.Context, req Request) Response {
resp := wh.Handler.Handle(ctx, req)
func (wh *Webhook) Handle(ctx context.Context, req Request) (resp Response) {
defer func() {
if r := recover(); r != nil {
err := fmt.Errorf("panic: %v [recovered]", r)
resp = Errored(http.StatusInternalServerError, err)
wh.log.Error(err, string(debug.Stack()))
}
}()
resp = wh.Handler.Handle(ctx, req)
if err := resp.Complete(req); err != nil {
wh.log.Error(err, "unable to encode response")
return Errored(http.StatusInternalServerError, errUnableToEncodeResponse)
Expand Down
9 changes: 8 additions & 1 deletion pkg/webhook/conversion/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"runtime/debug"

apix "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apimachinery/pkg/api/meta"
Expand Down Expand Up @@ -89,7 +90,13 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

// handles a version conversion request.
func (wh *Webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.ConversionResponse, error) {
func (wh *Webhook) handleConvertRequest(req *apix.ConversionRequest) (_ *apix.ConversionResponse, retErr error) {
defer func() {
if r := recover(); r != nil {
retErr = fmt.Errorf("panic: %v [recovered]", r)
log.Error(retErr, string(debug.Stack()))
}
}()
if req == nil {
return nil, fmt.Errorf("conversion request is nil")
}
Expand Down

0 comments on commit 3cffa52

Please sign in to comment.