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}, } } // Creates a new "redirect" GraphQL error pointing to the provided path. The // path should be broken down into path segments. The length of the path is // dependent on the type of resource being requested. func RedirectTo(path []string) *gqlerror.Error { return &gqlerror.Error{ Message: "The requested resource was moved", Extensions: map[string]any{ "code": Redirect, "redirect": path, }, } } // 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" Redirect ErrorCode = "ERR_REDIRECT" ) // 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") ErrRedirect = New(Redirect, "The requested resource was moved") )