mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 00:09:40 +02:00
fix(errors): wrap db errors, improve error handling (#8859)
* use error check func, wrap db object not found * add errorlint and fix all the linting errors * add exportloopref linter and fix errors * fix incorrect error details returned on an api * fix new errors * increase linter timeout * increase timeout to 10minutes * increase timeout to 10minutes * rebase and fix new lint errors * make CE match EE * fix govet issue
This commit is contained in:
parent
550e235d59
commit
334eee0c8c
52 changed files with 158 additions and 115 deletions
|
@ -1,6 +1,7 @@
|
|||
package edgegroups
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -39,8 +40,9 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
|||
|
||||
func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError {
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package edgejobs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
|
@ -42,8 +43,9 @@ func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *h
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package edgejobs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
|
@ -75,8 +76,9 @@ func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package edgejobs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -83,8 +84,9 @@ func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Reque
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package edgejobs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -62,8 +63,9 @@ func convertEndpointsToMetaObject(endpoints []portainer.EndpointID) map[portaine
|
|||
|
||||
func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError {
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -153,8 +153,8 @@ func registryAccessPoliciesContainsNamespace(registryAccess portainer.RegistryAc
|
|||
|
||||
func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User) ([]portainer.Registry, *httperror.HandlerError) {
|
||||
err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint)
|
||||
if err == security.ErrAuthorizationRequired {
|
||||
return nil, httperror.Forbidden("User is not authorized", errors.New("missing namespace query parameter"))
|
||||
if errors.Is(err, security.ErrAuthorizationRequired) {
|
||||
return nil, httperror.Forbidden("User is not authorized", err)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve info from request context", err)
|
||||
|
|
|
@ -29,7 +29,7 @@ type repositoryFilePreviewPayload struct {
|
|||
|
||||
func (payload *repositoryFilePreviewPayload) Validate(r *http.Request) error {
|
||||
if govalidator.IsNull(payload.Repository) || !govalidator.IsURL(payload.Repository) {
|
||||
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
|
||||
return errors.New("invalid repository URL. Must correspond to a valid URL format")
|
||||
}
|
||||
|
||||
if govalidator.IsNull(payload.Reference) {
|
||||
|
@ -37,7 +37,7 @@ func (payload *repositoryFilePreviewPayload) Validate(r *http.Request) error {
|
|||
}
|
||||
|
||||
if govalidator.IsNull(payload.TargetFile) {
|
||||
return errors.New("Invalid target filename.")
|
||||
return errors.New("invalid target filename")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -70,11 +70,11 @@ func (handler *Handler) gitOperationRepoFilePreview(w http.ResponseWriter, r *ht
|
|||
|
||||
err = handler.gitService.CloneRepository(projectPath, payload.Repository, payload.Reference, payload.Username, payload.Password, payload.TLSSkipVerify)
|
||||
if err != nil {
|
||||
if err == gittypes.ErrAuthenticationFailure {
|
||||
if errors.Is(err, gittypes.ErrAuthenticationFailure) {
|
||||
return httperror.BadRequest("Invalid git credential", err)
|
||||
}
|
||||
|
||||
newErr := fmt.Errorf("unable to clone git repository: %w", err)
|
||||
newErr := fmt.Errorf("unable to clone git repository, error: %w", err)
|
||||
return httperror.InternalServerError(newErr.Error(), newErr)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
bolterrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
)
|
||||
|
||||
|
@ -33,7 +32,7 @@ func (handler *Handler) openAMTActivate(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == bolterrors.ErrObjectNotFound {
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
} else if err != nil {
|
||||
return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
bolterrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
@ -33,7 +32,7 @@ func (handler *Handler) openAMTDevices(w http.ResponseWriter, r *http.Request) *
|
|||
}
|
||||
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == bolterrors.ErrObjectNotFound {
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
} else if err != nil {
|
||||
return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
bolterrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
"github.com/portainer/portainer/api/hostmanagement/openamt"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
@ -63,7 +62,7 @@ func (handler *Handler) openAMTHostInfo(w http.ResponseWriter, r *http.Request)
|
|||
log.Info().Int("endpointID", endpointID).Msg("OpenAMTHostInfo")
|
||||
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == bolterrors.ErrObjectNotFound {
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
} else if err != nil {
|
||||
return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err)
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"strconv"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
"github.com/portainer/portainer/api/kubernetes"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
@ -121,7 +120,7 @@ func (handler *Handler) kubeClient(next http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
httperror.WriteError(
|
||||
w,
|
||||
http.StatusNotFound,
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
models "github.com/portainer/portainer/api/http/models/kubernetes"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
)
|
||||
|
@ -23,7 +22,7 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r
|
|||
}
|
||||
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound(
|
||||
"Unable to find an environment with the specified identifier inside the database",
|
||||
err,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package stacks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -38,7 +39,8 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
|
|||
}
|
||||
|
||||
if err = deployments.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService); err != nil {
|
||||
if _, ok := err.(*deployments.StackAuthorMissingErr); ok {
|
||||
var StackAuthorMissingErr *deployments.StackAuthorMissingErr
|
||||
if errors.As(err, &StackAuthorMissingErr) {
|
||||
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package tags
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -34,8 +35,9 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
|||
|
||||
func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError {
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package tags
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -41,8 +42,9 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
var handlerError *httperror.HandlerError
|
||||
if errors.As(err, &handlerError) {
|
||||
return handlerError
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package users
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -66,7 +67,7 @@ func (handler *Handler) userRemoveAccessToken(w http.ResponseWriter, r *http.Req
|
|||
|
||||
err = handler.apiKeyService.DeleteAPIKey(portainer.APIKeyID(apiKeyID))
|
||||
if err != nil {
|
||||
if err == apikey.ErrInvalidAPIKey {
|
||||
if errors.Is(err, apikey.ErrInvalidAPIKey) {
|
||||
return httperror.NotFound("Unable to find an api-key with the specified identifier inside the database", err)
|
||||
}
|
||||
return httperror.InternalServerError("Unable to remove the api-key from the user", err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package websocket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
@ -11,7 +12,7 @@ import (
|
|||
func hijackRequest(websocketConn *websocket.Conn, httpConn *httputil.ClientConn, request *http.Request) error {
|
||||
// Server hijacks the connection, error 'connection closed' expected
|
||||
resp, err := httpConn.Do(request)
|
||||
if err != httputil.ErrPersistEOF {
|
||||
if !errors.Is(err, httputil.ErrPersistEOF) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue