func NewHTTPErrResp()

in internal/pkg/api/error.go [71:561]


func NewHTTPErrResp(err error) HTTPErrResp {
	errTable := []struct {
		target error
		meta   HTTPErrResp
	}{
		{
			ErrAgentNotFound,
			HTTPErrResp{
				http.StatusNotFound,
				"AgentNotFound",
				"agent could not be found",
				zerolog.WarnLevel,
			},
		},
		{
			ErrAPIKeyNotEnabled,
			HTTPErrResp{
				http.StatusUnauthorized,
				"Unauthorized",
				"ApiKey not enabled",
				zerolog.InfoLevel,
			},
		},
		{
			context.Canceled,
			HTTPErrResp{
				499,
				"StatusClientClosedRequest",
				"server is stopping",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAgentNotReplaceable,
			HTTPErrResp{
				http.StatusForbidden,
				"AgentNotReplaceable",
				"existing agent cannot be replaced",
				zerolog.WarnLevel,
			},
		},
		{
			ErrInvalidUserAgent,
			HTTPErrResp{
				http.StatusBadRequest,
				"InvalidUserAgent",
				"user-agent is invalid",
				zerolog.InfoLevel,
			},
		},
		{
			ErrUnsupportedVersion,
			HTTPErrResp{
				http.StatusBadRequest,
				"UnsupportedVersion",
				"version is not supported",
				zerolog.InfoLevel,
			},
		},
		{
			dl.ErrNotFound,
			HTTPErrResp{
				http.StatusNotFound,
				"NotFound",
				"not found",
				zerolog.WarnLevel,
			},
		},
		{
			ErrorThrottle,
			HTTPErrResp{
				http.StatusTooManyRequests,
				"TooManyRequests",
				"too many requests",
				zerolog.DebugLevel,
			},
		},
		{
			limit.ErrRateLimit,
			HTTPErrResp{
				http.StatusTooManyRequests,
				"RateLimit",
				"exceeded the rate limit",
				zerolog.WarnLevel,
			},
		},
		{
			limit.ErrMaxLimit,
			HTTPErrResp{
				http.StatusTooManyRequests,
				"MaxLimit",
				"exceeded the max limit",
				zerolog.WarnLevel,
			},
		},
		{
			apikey.ErrElasticsearchAuthLimit,
			HTTPErrResp{
				http.StatusTooManyRequests,
				"ElasticsearchAPIKeyAuthLimit",
				"exceeded the elasticsearch api key auth limit",
				zerolog.WarnLevel,
			},
		},
		{
			os.ErrDeadlineExceeded,
			HTTPErrResp{
				http.StatusRequestTimeout,
				"RequestTimeout",
				"timeout on request",
				zerolog.InfoLevel,
			},
		},
		{
			ErrUpdatingInactiveAgent,
			HTTPErrResp{
				http.StatusUnauthorized,
				"Unauthorized",
				"Agent not active",
				zerolog.InfoLevel,
			},
		},
		{
			ErrTransitHashRequired,
			HTTPErrResp{
				http.StatusBadRequest,
				"TransitHashRequired",
				"Transit hash required",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAgentIdentity,
			HTTPErrResp{
				http.StatusForbidden,
				"ErrAgentIdentity",
				"Agent header contains wrong identifier",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAgentCorrupted,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrAgentCorrupted",
				"Agent record corrupted",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAgentInactive,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrAgentInactive",
				"Agent inactive",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAPIKeyNotEnabled,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrAPIKeyNotEnabled",
				"APIKey not enabled",
				zerolog.InfoLevel,
			},
		},
		{
			ErrFileInfoBodyRequired,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrFileInfoBodyRequired",
				"file info body is required",
				zerolog.InfoLevel,
			},
		},
		{
			ErrAgentIDMissing,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrAgentIDMissing",
				"equired field agent_id is missing",
				zerolog.InfoLevel,
			},
		},
		{
			ErrTLSRequired,
			HTTPErrResp{
				http.StatusNotImplemented,
				"ErrTLSRequired",
				"server must run with tls to use this endpoint",
				zerolog.InfoLevel,
			},
		},
		// apikey
		{
			apikey.ErrNoAuthHeader,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrNoAuthHeader",
				"no authorization header",
				zerolog.InfoLevel,
			},
		},
		{
			apikey.ErrMalformedHeader,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrMalformedHeader",
				"malformed authorization header",
				zerolog.InfoLevel,
			},
		},
		{
			apikey.ErrUnauthorized,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrUnauthorized",
				"unauthorized",
				zerolog.InfoLevel,
			},
		},
		{
			apikey.ErrMalformedToken,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrMalformedToken",
				"malformed token",
				zerolog.InfoLevel,
			},
		},
		{
			apikey.ErrInvalidToken,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrInvalidToken",
				"token not valid utf8",
				zerolog.InfoLevel,
			},
		},
		{
			apikey.ErrAPIKeyNotFound,
			HTTPErrResp{
				http.StatusUnauthorized,
				"ErrAPIKeyNotFound",
				"api key not found",
				zerolog.InfoLevel,
			},
		},
		// upload
		{
			uploader.ErrInvalidUploadID,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrAPIKeyNotFound",
				"active upload not found with this ID, it may be expired",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrFileSizeTooLarge,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrFileSizeTooLarge",
				"this file exceeds the maximum allowed file size",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrMissingChunks,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrMissingChunks",
				"file data incomplete, not all chunks were uploaded",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrHashMismatch,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrHashMismatch",
				"hash does not match",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrUploadExpired,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrUploadExpired",
				"upload has expired",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrUploadStopped,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrUploadStopped",
				"upload has stopped",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrInvalidChunkNum,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrInvalidChunkNum",
				"invalid chunk number",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrFailValidation,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrFailValidation",
				"file contents failed validation",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrStatusNoUploads,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrStatusNoUploads",
				"file closed, not accepting uploads",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrPayloadRequired,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrPayloadRequired",
				"upload start payload required",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrFileSizeRequired,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrFileSizeRequired",
				"file.size is required",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrInvalidFileSize,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrInvalidFileSize",
				"",
				zerolog.InfoLevel,
			},
		},
		{
			uploader.ErrFieldRequired,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrFieldRequired",
				"",
				zerolog.InfoLevel,
			},
		},
		// Version
		{
			ErrInvalidAPIVersionFormat,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrInvalidAPIVersionFormat",
				"",
				zerolog.InfoLevel,
			},
		},
		{
			ErrUnsupportedAPIVersion,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrUnsupportedAPIVersion",
				"",
				zerolog.InfoLevel,
			},
		},
		// file
		{
			delivery.ErrNoFile,
			HTTPErrResp{
				http.StatusNotFound,
				"ErrNoFile",
				"file not found",
				zerolog.InfoLevel,
			},
		},
		{
			file.ErrInvalidID,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrInvalidFileID",
				"ErrInvalidID",
				zerolog.InfoLevel,
			},
		},
		{
			ErrPolicyNotFound,
			HTTPErrResp{
				http.StatusBadRequest,
				"ErrPolicyNotFound",
				"ErrPolicyNotFound",
				zerolog.InfoLevel,
			},
		},
		// audit unenroll
		{
			ErrAuditUnenrollReason,
			HTTPErrResp{
				http.StatusConflict,
				"ErrAuditReasonConflict",
				"agent document contains audit_unenroll_reason",
				zerolog.InfoLevel,
			},
		},
	}

	for _, e := range errTable {
		if errors.Is(err, e.target) {
			if len(e.meta.Message) == 0 {
				return HTTPErrResp{
					e.meta.StatusCode,
					e.meta.Error,
					err.Error(),
					e.meta.Level,
				}
			}

			return e.meta
		}
	}

	var drErr *BadRequestErr
	if errors.As(err, &drErr) {
		return HTTPErrResp{
			http.StatusBadRequest,
			"BadRequest",
			err.Error(),
			zerolog.ErrorLevel,
		}
	}

	// If it's a JSON marshal error
	var jErr *json.MarshalerError
	if errors.As(err, &jErr) {
		return HTTPErrResp{
			http.StatusInternalServerError,
			err.Error(),
			"Fleet server unable to marshall JSON",
			zerolog.ErrorLevel,
		}
	}

	var esErr *es.ErrElastic
	if errors.As(err, &esErr) {
		return HTTPErrResp{
			http.StatusServiceUnavailable,
			esErr.Error(),
			"elasticsearch error",
			zerolog.ErrorLevel,
		}
	}

	// Check if we have encountered a connectivity error
	// Predicate taken from https://github.com/golang/go/blob/go1.17.5/src/net/dial_test.go#L798
	if strings.Contains(err.Error(), "connection refused") {
		return HTTPErrResp{
			http.StatusServiceUnavailable,
			"ServiceUnavailable",
			"Fleet server unable to communicate with Elasticsearch",
			zerolog.InfoLevel,
		}
	}

	// Default
	return HTTPErrResp{
		StatusCode: http.StatusInternalServerError,
		Error:      "BadRequest",
		Message:    err.Error(),
		Level:      zerolog.InfoLevel,
	}
}