feat: initial version
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package presenter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
func New[C ~string, E ~string](logger *slog.Logger, codes []C, entities []E, internalErrorCode C) func(ctx context.Context, e error) *gqlerror.Error {
|
||||
return func(ctx context.Context, e error) *gqlerror.Error {
|
||||
err := graphql.DefaultErrorPresenter(ctx, e)
|
||||
var codedError CodedError
|
||||
if errors.As(e, &codedError) {
|
||||
code := toModelErrorCode(codedError.Code, codes, internalErrorCode)
|
||||
errorEntity := toModelErrorEntity(codedError.Entity, entities)
|
||||
extensions := map[string]interface{}{"code": code}
|
||||
if len(errorEntity) > 0 {
|
||||
extensions["errorEntity"] = errorEntity
|
||||
}
|
||||
if len(codedError.Params) > 0 {
|
||||
extensions["params"] = codedError.Params
|
||||
}
|
||||
err.Extensions = extensions
|
||||
} else {
|
||||
err.Extensions = map[string]interface{}{"code": internalErrorCode}
|
||||
}
|
||||
if logError(e) {
|
||||
logger.ErrorContext(ctx, fmt.Sprintf("%v", e))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func logError(err error) bool {
|
||||
return !errors.Is(err, context.Canceled)
|
||||
}
|
||||
|
||||
func toModelErrorCode[C ~string](code Code, codes []C, internalErrorCode C) C {
|
||||
for _, c := range codes {
|
||||
if string(c) == string(code) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return internalErrorCode
|
||||
}
|
||||
|
||||
func toModelErrorEntity[E ~string](entity Entity, entities []E) E {
|
||||
for _, e := range entities {
|
||||
if string(e) == string(entity) {
|
||||
return e
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user