Initial QSfera import
This commit is contained in:
+198
@@ -0,0 +1,198 @@
|
||||
package gqlerror
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
)
|
||||
|
||||
// Error is the standard graphql error type described in https://spec.graphql.org/draft/#sec-Errors
|
||||
type Error struct {
|
||||
Err error `json:"-"`
|
||||
Message string `json:"message"`
|
||||
Path ast.Path `json:"path,omitempty"`
|
||||
Locations []Location `json:"locations,omitempty"`
|
||||
Extensions map[string]any `json:"extensions,omitempty"`
|
||||
Rule string `json:"-"`
|
||||
}
|
||||
|
||||
func (err *Error) SetFile(file string) {
|
||||
if file == "" {
|
||||
return
|
||||
}
|
||||
if err.Extensions == nil {
|
||||
err.Extensions = map[string]any{}
|
||||
}
|
||||
|
||||
err.Extensions["file"] = file
|
||||
}
|
||||
|
||||
type Location struct {
|
||||
Line int `json:"line,omitempty"`
|
||||
Column int `json:"column,omitempty"`
|
||||
}
|
||||
|
||||
type List []*Error
|
||||
|
||||
func (err *Error) Error() string {
|
||||
var res strings.Builder
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
filename, _ := err.Extensions["file"].(string)
|
||||
if filename == "" {
|
||||
filename = "input"
|
||||
}
|
||||
res.WriteString(filename)
|
||||
|
||||
if len(err.Locations) > 0 {
|
||||
res.WriteByte(':')
|
||||
res.WriteString(strconv.Itoa(err.Locations[0].Line))
|
||||
res.WriteByte(':')
|
||||
res.WriteString(strconv.Itoa(err.Locations[0].Column))
|
||||
}
|
||||
|
||||
res.WriteString(": ")
|
||||
if ps := err.pathString(); ps != "" {
|
||||
res.WriteString(ps)
|
||||
res.WriteByte(' ')
|
||||
}
|
||||
|
||||
res.WriteString(err.Message)
|
||||
|
||||
return res.String()
|
||||
}
|
||||
|
||||
func (err *Error) pathString() string {
|
||||
return err.Path.String()
|
||||
}
|
||||
|
||||
func (err *Error) Unwrap() error {
|
||||
return err.Err
|
||||
}
|
||||
|
||||
func (err *Error) AsError() error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (errs List) Error() string {
|
||||
var buf strings.Builder
|
||||
for _, err := range errs {
|
||||
buf.WriteString(err.Error())
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (errs List) Is(target error) bool {
|
||||
for _, err := range errs {
|
||||
if errors.Is(err, target) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (errs List) As(target any) bool {
|
||||
for _, err := range errs {
|
||||
if errors.As(err, target) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (errs List) Unwrap() []error {
|
||||
l := make([]error, len(errs))
|
||||
for i, err := range errs {
|
||||
l[i] = err
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func WrapPath(path ast.Path, err error) *Error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &Error{
|
||||
Err: err,
|
||||
Message: err.Error(),
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
func Wrap(err error) *Error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &Error{
|
||||
Err: err,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
func WrapIfUnwrapped(err error) *Error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
gqlErr := &Error{}
|
||||
if errors.As(err, &gqlErr) {
|
||||
return gqlErr
|
||||
}
|
||||
return &Error{
|
||||
Err: err,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
func Errorf(message string, args ...any) *Error {
|
||||
return &Error{
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorPathf(path ast.Path, message string, args ...any) *Error {
|
||||
return &Error{
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorPosf(pos *ast.Position, message string, args ...any) *Error {
|
||||
if pos == nil {
|
||||
return ErrorLocf(
|
||||
"",
|
||||
-1,
|
||||
-1,
|
||||
message,
|
||||
args...,
|
||||
)
|
||||
}
|
||||
return ErrorLocf(
|
||||
pos.Src.Name,
|
||||
pos.Line,
|
||||
pos.Column,
|
||||
message,
|
||||
args...,
|
||||
)
|
||||
}
|
||||
|
||||
func ErrorLocf(file string, line, col int, message string, args ...any) *Error {
|
||||
var extensions map[string]any
|
||||
if file != "" {
|
||||
extensions = map[string]any{"file": file}
|
||||
}
|
||||
return &Error{
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
Extensions: extensions,
|
||||
Locations: []Location{
|
||||
{Line: line, Column: col},
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user