package errors
import (
"errors"
"fmt"
"github.com/vektah/gqlparser/v2/gqlerror"
)
type ErrorCode string
// Creates a new GraphQL error with a standard error code.
func New(code ErrorCode, message string) *gqlerror.Error {
return &gqlerror.Error{
Message: message,
Extensions: map[string]any{"code": code},
}
}
// Creates a new GraphQL error with a standard error code.
func Errorf(code ErrorCode, format string, a ...any) *gqlerror.Error {
return &gqlerror.Error{
Message: fmt.Sprintf(format, a...),
Extensions: map[string]any{"code": code},
}
}
// Sets the field name that caused the error
func Field(err *gqlerror.Error, field string) *gqlerror.Error {
err.Extensions["field"] = field
return err
}
// Returns true if the first GraphQL error has the same error code as the
// reference error. This should be used, for example, to test an error from
// client.Do against an error initialized by this module (e.g.
// ErrAccessDenied). These errors do not work with the Go standard library's
// errors.Is function, nor with ==, thus this function.
func Is(err error, ref *gqlerror.Error) bool {
var gqlerr *gqlerror.Error
if !errors.As(err, &gqlerr) {
return false
}
if code, ok := gqlerr.Extensions["code"]; ok {
if refCode, ok := ref.Extensions["code"]; ok {
return code == refCode
}
}
return false
}
// Error codes as string constants
var (
AccessDenied ErrorCode = "ERR_ACCESS_DENIED"
NotFound ErrorCode = "ERR_NOT_FOUND"
Unsupported ErrorCode = "ERR_UNSUPPORTED"
Unauthorized ErrorCode = "ERR_UNAUTHORIZED"
InternalError ErrorCode = "ERR_INTERNAL"
Timeout ErrorCode = "ERR_TIMEOUT"
)
// Error codes as Go errors
var (
ErrAccessDenied = New(AccessDenied, "Access denied")
ErrNotFound = New(NotFound, "Resource not found")
ErrUnsupported = New(Unsupported, "Not supported")
ErrUnauthorized = New(Unauthorized, "Unauthorized")
ErrInternalError = New(InternalError, "Internal server error")
ErrTimeout = New(Timeout, "Operation timed out")
)