Files
Leonor Oliveira a9ef8bcced Use logging from app sdk in the resource mod (#103281)
* Use logging from app sdk in the resource mod

* make update-workspace

* Use app-sdk logging in SQL backend

* Use grafana-app logging in tests

* make update-workspace

* make update-workspace

* make update-workspace

* Use default logging

* Remove dependency on grafana/grafana

* Fix imports
2025-04-08 15:35:11 +02:00

126 lines
2.9 KiB
Go

package resource
import (
"errors"
"net/http"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
grpcstatus "google.golang.org/grpc/status"
)
// Package-level errors.
var (
ErrOptimisticLockingFailed = errors.New("optimistic locking failed")
ErrNotImplementedYet = errors.New("not implemented yet")
)
var (
ErrResourceAlreadyExists error = &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Reason: metav1.StatusReasonAlreadyExists,
Message: "the resource already exists",
Code: http.StatusConflict,
},
}
)
func NewBadRequestError(msg string) *ErrorResult {
return &ErrorResult{
Message: msg,
Code: http.StatusBadRequest,
Reason: string(metav1.StatusReasonBadRequest),
}
}
func NewNotFoundError(key *ResourceKey) *ErrorResult {
return &ErrorResult{
Code: http.StatusNotFound,
Details: &ErrorDetails{
Group: key.Group,
Kind: key.Resource, // yup, resource as kind same is true in apierrors.NewNotFound()
Name: key.Name,
},
}
}
// Convert golang errors to status result errors that can be returned to a client
func AsErrorResult(err error) *ErrorResult {
if err == nil {
return nil
}
var apistatus apierrors.APIStatus
if errors.As(err, &apistatus) {
s := apistatus.Status()
res := &ErrorResult{
Message: s.Message,
Reason: string(s.Reason),
Code: s.Code,
}
if s.Details != nil {
res.Details = &ErrorDetails{
Group: s.Details.Group,
Kind: s.Details.Kind,
Name: s.Details.Name,
Uid: string(s.Details.UID),
RetryAfterSeconds: s.Details.RetryAfterSeconds,
}
for _, c := range s.Details.Causes {
res.Details.Causes = append(res.Details.Causes, &ErrorCause{
Reason: string(c.Type),
Message: c.Message,
Field: c.Field,
})
}
}
return res
}
code := 500
st, ok := grpcstatus.FromError(err)
if ok {
code = runtime.HTTPStatusFromCode(st.Code())
}
return &ErrorResult{
Message: err.Error(),
Code: int32(code),
}
}
func GetError(res *ErrorResult) error {
if res == nil {
return nil
}
status := &apierrors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: res.Code,
Reason: metav1.StatusReason(res.Reason),
Message: res.Message,
}}
if res.Details != nil {
status.ErrStatus.Details = &metav1.StatusDetails{
Group: res.Details.Group,
Kind: res.Details.Kind,
Name: res.Details.Name,
UID: types.UID(res.Details.Uid),
RetryAfterSeconds: res.Details.RetryAfterSeconds,
}
for _, c := range res.Details.Causes {
status.ErrStatus.Details.Causes = append(status.ErrStatus.Details.Causes, metav1.StatusCause{
Type: metav1.CauseType(c.Reason),
Message: c.Message,
Field: c.Field,
})
}
}
return status
}