...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/util/error.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/util

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"os"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"github.com/pkg/errors"
    27  
    28  	errorsutil "k8s.io/apimachinery/pkg/util/errors"
    29  )
    30  
    31  const (
    32  	// DefaultErrorExitCode defines exit the code for failed action generally
    33  	DefaultErrorExitCode = 1
    34  	// PreFlightExitCode defines exit the code for preflight checks
    35  	PreFlightExitCode = 2
    36  	// ValidationExitCode defines the exit code validation checks
    37  	ValidationExitCode = 3
    38  )
    39  
    40  var (
    41  	// ErrInvalidSubCommandMsg is an error message returned on invalid subcommands
    42  	ErrInvalidSubCommandMsg = "invalid subcommand"
    43  	// ErrExit is an error returned when kubeadm is about to exit
    44  	ErrExit = errors.New("exit")
    45  )
    46  
    47  // fatal prints the message if set and then exits.
    48  func fatal(msg string, code int) {
    49  	if len(msg) > 0 {
    50  		// add newline if needed
    51  		if !strings.HasSuffix(msg, "\n") {
    52  			msg += "\n"
    53  		}
    54  
    55  		fmt.Fprint(os.Stderr, msg)
    56  	}
    57  	os.Exit(code)
    58  }
    59  
    60  // CheckErr prints a user friendly error to STDERR and exits with a non-zero
    61  // exit code. Unrecognized errors will be printed with an "error: " prefix.
    62  //
    63  // This method is generic to the command in use and may be used by non-Kubectl
    64  // commands.
    65  func CheckErr(err error) {
    66  	checkErr(err, fatal)
    67  }
    68  
    69  // preflightError allows us to know if the error is a preflight error or not
    70  // defining the interface here avoids an import cycle of pulling in preflight into the util package
    71  type preflightError interface {
    72  	Preflight() bool
    73  }
    74  
    75  // checkErr formats a given error as a string and calls the passed handleErr
    76  // func with that string and an exit code.
    77  func checkErr(err error, handleErr func(string, int)) {
    78  	if err == nil {
    79  		return
    80  	}
    81  
    82  	msg := fmt.Sprintf("%s\nTo see the stack trace of this error execute with --v=5 or higher", err.Error())
    83  	// check if the verbosity level in klog is high enough and print a stack trace.
    84  	f := flag.CommandLine.Lookup("v")
    85  	if f != nil {
    86  		// assume that the "v" flag contains a parseable Int32 as per klog's "Level" type alias,
    87  		// thus no error from ParseInt is handled here.
    88  		if v, e := strconv.ParseInt(f.Value.String(), 10, 32); e == nil {
    89  			// https://git.k8s.io/community/contributors/devel/sig-instrumentation/logging.md
    90  			// klog.V(5) - Trace level verbosity
    91  			if v > 4 {
    92  				msg = fmt.Sprintf("%+v", err)
    93  			}
    94  		}
    95  	}
    96  
    97  	switch {
    98  	case err == ErrExit:
    99  		handleErr("", DefaultErrorExitCode)
   100  	case strings.Contains(err.Error(), ErrInvalidSubCommandMsg):
   101  		handleErr(err.Error(), DefaultErrorExitCode)
   102  	default:
   103  		switch err.(type) {
   104  		case preflightError:
   105  			handleErr(msg, PreFlightExitCode)
   106  		case errorsutil.Aggregate:
   107  			handleErr(msg, ValidationExitCode)
   108  
   109  		default:
   110  			handleErr(msg, DefaultErrorExitCode)
   111  		}
   112  	}
   113  }
   114  
   115  // FormatErrMsg returns a human-readable string describing the slice of errors passed to the function
   116  func FormatErrMsg(errs []error) string {
   117  	var errMsg string
   118  	for _, err := range errs {
   119  		errMsg = fmt.Sprintf("%s\t- %s\n", errMsg, err.Error())
   120  	}
   121  	return errMsg
   122  }
   123  

View as plain text