Files
genqlient/generate/errors.go
T

133 lines
2.7 KiB
Go

package generate
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/gqlerror"
)
type errorPos struct {
filename string
line, col int
}
func (pos *errorPos) String() string {
filename, lineOffset := splitFilename(pos.filename)
line := lineOffset + pos.line
if line != 0 {
return fmt.Sprintf("%v:%v", filename, line)
} else {
return filename
}
}
type genqlientError struct {
pos *errorPos
msg string
wrapped error
}
func splitFilename(filename string) (name string, lineOffset int) {
split := strings.Split(filename, ":")
if len(split) != 2 {
return filename, 0
}
offset, err := strconv.Atoi(split[1])
if err != nil {
return split[0], 0
}
return split[0], offset - 1
}
func (err *genqlientError) Error() string {
if err.pos != nil {
return err.pos.String() + ": " + err.msg
} else {
return err.msg
}
}
func (err *genqlientError) Unwrap() error {
return err.wrapped
}
func errorf(pos *ast.Position, msg string, args ...interface{}) error {
// TODO: alternately accept a filename only, or maybe even a go-parser pos
// We do all our own wrapping, because if the wrapped error already has a
// pos, we want to extract it out and put it at the front, not in the
// middle.
var wrapped error
var wrapIndex int
for i, arg := range args {
if wrapped == nil {
var ok bool
wrapped, ok = arg.(error)
if ok {
wrapIndex = i
}
}
}
var wrappedGenqlient *genqlientError
isGenqlient := errors.As(wrapped, &wrappedGenqlient)
var wrappedGraphQL *gqlerror.Error
isGraphQL := errors.As(wrapped, &wrappedGraphQL)
if !isGraphQL {
var wrappedGraphQLList gqlerror.List
isGraphQLList := errors.As(wrapped, &wrappedGraphQLList)
if isGraphQLList && len(wrappedGraphQLList) > 0 {
isGraphQL = true
wrappedGraphQL = wrappedGraphQLList[0]
}
}
var errPos *errorPos
if pos != nil {
errPos = &errorPos{
filename: pos.Src.Name,
line: pos.Line,
col: pos.Column,
}
} else if isGenqlient {
errPos = wrappedGenqlient.pos
} else if isGraphQL {
filename, _ := wrappedGraphQL.Extensions["file"].(string)
if filename != "" {
var loc gqlerror.Location
if len(wrappedGraphQL.Locations) > 0 {
loc = wrappedGraphQL.Locations[0]
}
errPos = &errorPos{
filename: filename,
line: loc.Line,
col: loc.Column,
}
}
}
if wrapped != nil {
errText := wrapped.Error()
if isGenqlient {
errText = wrappedGenqlient.msg
} else if isGraphQL {
errText = wrappedGraphQL.Message
}
args[wrapIndex] = errText
}
msg = fmt.Sprintf(msg, args...)
return &genqlientError{
msg: msg,
pos: errPos,
wrapped: wrapped,
}
}