github.com/boynux/docker@v1.11.0-rc4/api/server/httputils/errors.go (about)

     1  package httputils
     2  
     3  import (
     4  	"net/http"
     5  	"strings"
     6  
     7  	"github.com/Sirupsen/logrus"
     8  )
     9  
    10  // httpStatusError is an interface
    11  // that errors with custom status codes
    12  // implement to tell the api layer
    13  // which response status to set.
    14  type httpStatusError interface {
    15  	HTTPErrorStatusCode() int
    16  }
    17  
    18  // inputValidationError is an interface
    19  // that errors generated by invalid
    20  // inputs can implement to tell the
    21  // api layer to set a 400 status code
    22  // in the response.
    23  type inputValidationError interface {
    24  	IsValidationError() bool
    25  }
    26  
    27  // WriteError decodes a specific docker error and sends it in the response.
    28  func WriteError(w http.ResponseWriter, err error) {
    29  	if err == nil || w == nil {
    30  		logrus.WithFields(logrus.Fields{"error": err, "writer": w}).Error("unexpected HTTP error handling")
    31  		return
    32  	}
    33  
    34  	var statusCode int
    35  	errMsg := err.Error()
    36  
    37  	switch e := err.(type) {
    38  	case httpStatusError:
    39  		statusCode = e.HTTPErrorStatusCode()
    40  	case inputValidationError:
    41  		statusCode = http.StatusBadRequest
    42  	default:
    43  		// FIXME: this is brittle and should not be necessary, but we still need to identify if
    44  		// there are errors falling back into this logic.
    45  		// If we need to differentiate between different possible error types,
    46  		// we should create appropriate error types that implement the httpStatusError interface.
    47  		errStr := strings.ToLower(errMsg)
    48  		for keyword, status := range map[string]int{
    49  			"not found":             http.StatusNotFound,
    50  			"no such":               http.StatusNotFound,
    51  			"bad parameter":         http.StatusBadRequest,
    52  			"conflict":              http.StatusConflict,
    53  			"impossible":            http.StatusNotAcceptable,
    54  			"wrong login/password":  http.StatusUnauthorized,
    55  			"hasn't been activated": http.StatusForbidden,
    56  		} {
    57  			if strings.Contains(errStr, keyword) {
    58  				statusCode = status
    59  				break
    60  			}
    61  		}
    62  	}
    63  
    64  	if statusCode == 0 {
    65  		statusCode = http.StatusInternalServerError
    66  	}
    67  
    68  	http.Error(w, errMsg, statusCode)
    69  }