...
1 package gqlerror
2
3 import (
4 "bytes"
5 "fmt"
6 "strconv"
7
8 "github.com/vektah/gqlparser/ast"
9 )
10
11
12 type Error struct {
13 Message string `json:"message"`
14 Path []interface{} `json:"path,omitempty"`
15 Locations []Location `json:"locations,omitempty"`
16 Extensions map[string]interface{} `json:"extensions,omitempty"`
17 Rule string `json:"-"`
18 }
19
20 func (err *Error) SetFile(file string) {
21 if file == "" {
22 return
23 }
24 if err.Extensions == nil {
25 err.Extensions = map[string]interface{}{}
26 }
27
28 err.Extensions["file"] = file
29 }
30
31 type Location struct {
32 Line int `json:"line,omitempty"`
33 Column int `json:"column,omitempty"`
34 }
35
36 type List []*Error
37
38 func (err *Error) Error() string {
39 var res bytes.Buffer
40 if err == nil {
41 return ""
42 }
43 filename, _ := err.Extensions["file"].(string)
44 if filename == "" {
45 filename = "input"
46 }
47 res.WriteString(filename)
48
49 if len(err.Locations) > 0 {
50 res.WriteByte(':')
51 res.WriteString(strconv.Itoa(err.Locations[0].Line))
52 }
53
54 res.WriteString(": ")
55 if ps := err.pathString(); ps != "" {
56 res.WriteString(ps)
57 res.WriteByte(' ')
58 }
59
60 res.WriteString(err.Message)
61
62 return res.String()
63 }
64
65 func (err Error) pathString() string {
66 var str bytes.Buffer
67 for i, v := range err.Path {
68
69 switch v := v.(type) {
70 case int, int64:
71 str.WriteString(fmt.Sprintf("[%d]", v))
72 default:
73 if i != 0 {
74 str.WriteByte('.')
75 }
76 str.WriteString(fmt.Sprint(v))
77 }
78 }
79 return str.String()
80 }
81
82 func (errs List) Error() string {
83 var buf bytes.Buffer
84 for _, err := range errs {
85 buf.WriteString(err.Error())
86 buf.WriteByte('\n')
87 }
88 return buf.String()
89 }
90
91 func WrapPath(path []interface{}, err error) *Error {
92 return &Error{
93 Message: err.Error(),
94 Path: path,
95 }
96 }
97
98 func Errorf(message string, args ...interface{}) *Error {
99 return &Error{
100 Message: fmt.Sprintf(message, args...),
101 }
102 }
103
104 func ErrorPathf(path []interface{}, message string, args ...interface{}) *Error {
105 return &Error{
106 Message: fmt.Sprintf(message, args...),
107 Path: path,
108 }
109 }
110
111 func ErrorPosf(pos *ast.Position, message string, args ...interface{}) *Error {
112 return ErrorLocf(
113 pos.Src.Name,
114 pos.Line,
115 pos.Column,
116 message,
117 args...,
118 )
119 }
120
121 func ErrorLocf(file string, line int, col int, message string, args ...interface{}) *Error {
122 var extensions map[string]interface{}
123 if file != "" {
124 extensions = map[string]interface{}{"file": file}
125 }
126 return &Error{
127 Message: fmt.Sprintf(message, args...),
128 Extensions: extensions,
129 Locations: []Location{
130 {Line: line, Column: col},
131 },
132 }
133 }
134
View as plain text