1
1
// @flow strict
2
2
3
+ // FIXME:
4
+ // flowlint uninitialized-instance-property:off
5
+
3
6
import isObjectLike from '../jsutils/isObjectLike' ;
7
+ import { SYMBOL_TO_STRING_TAG } from '../polyfills/symbols' ;
4
8
5
9
import { type ASTNode } from '../language/ast' ;
6
10
import { type Source } from '../language/source' ;
@@ -13,17 +17,7 @@ import { printLocation, printSourceLocation } from '../language/printLocation';
13
17
* and stack trace, it also includes information about the locations in a
14
18
* GraphQL document and/or execution result that correspond to the Error.
15
19
*/
16
- declare class GraphQLError extends Error {
17
- constructor (
18
- message : string ,
19
- nodes ?: $ReadOnlyArray < ASTNode > | ASTNode | void | null ,
20
- source ?: ?Source ,
21
- positions ?: ?$ReadOnlyArray < number > ,
22
- path ?: ?$ReadOnlyArray < string | number > ,
23
- originalError ?: ?Error ,
24
- extensions ?: ?{ [ key : string ] : mixed , ... } ,
25
- ) : void ;
26
-
20
+ export class GraphQLError extends Error {
27
21
/**
28
22
* A message describing the Error for debugging purposes.
29
23
*
@@ -81,148 +75,151 @@ declare class GraphQLError extends Error {
81
75
* Extension fields to add to the formatted error.
82
76
*/
83
77
+ extensions : { [ key : string ] : mixed , ... } | void ;
84
- }
85
78
86
- export function GraphQLError ( // eslint-disable-line no-redeclare
87
- message : string ,
88
- nodes ?: $ReadOnlyArray < ASTNode > | ASTNode | void ,
89
- source ?: ?Source ,
90
- positions ?: ?$ReadOnlyArray < number > ,
91
- path ?: ?$ReadOnlyArray < string | number > ,
92
- originalError ?: ?Error & { + extensions : mixed , ... } ,
93
- extensions ?: ?{ [ key : string ] : mixed , ... } ,
94
- ) {
95
- // Compute list of blame nodes.
96
- const _nodes = Array . isArray ( nodes )
97
- ? nodes . length !== 0
98
- ? nodes
99
- : undefined
100
- : nodes
101
- ? [ nodes ]
102
- : undefined ;
103
-
104
- // Compute locations in the source for the given nodes/positions.
105
- let _source = source ;
106
- if ( ! _source && _nodes ) {
107
- const node = _nodes [ 0 ] ;
108
- _source = node && node . loc && node . loc . source ;
109
- }
79
+ constructor (
80
+ message : string ,
81
+ nodes ?: $ReadOnlyArray < ASTNode > | ASTNode | void | null ,
82
+ source ?: ?Source ,
83
+ positions ?: ?$ReadOnlyArray < number > ,
84
+ path ?: ?$ReadOnlyArray < string | number > ,
85
+ originalError ?: ?( Error & { + extensions ? : mixed , ... } ) ,
86
+ extensions ?: ?{ [ key : string ] : mixed , ... } ,
87
+ ) : void {
88
+ super ( message ) ;
89
+
90
+ // Compute list of blame nodes.
91
+ const _nodes = Array . isArray ( nodes )
92
+ ? nodes . length !== 0
93
+ ? nodes
94
+ : undefined
95
+ : nodes
96
+ ? [ nodes ]
97
+ : undefined ;
98
+
99
+ // Compute locations in the source for the given nodes/positions.
100
+ let _source = source ;
101
+ if ( ! _source && _nodes ) {
102
+ const node = _nodes [ 0 ] ;
103
+ _source = node && node . loc && node . loc . source ;
104
+ }
110
105
111
- let _positions = positions ;
112
- if ( ! _positions && _nodes ) {
113
- _positions = _nodes . reduce ( ( list , node ) => {
114
- if ( node . loc ) {
115
- list . push ( node . loc . start ) ;
116
- }
117
- return list ;
118
- } , [ ] ) ;
119
- }
120
- if ( _positions && _positions . length === 0 ) {
121
- _positions = undefined ;
122
- }
106
+ let _positions = positions ;
107
+ if ( ! _positions && _nodes ) {
108
+ _positions = _nodes . reduce ( ( list , node ) => {
109
+ if ( node . loc ) {
110
+ list . push ( node . loc . start ) ;
111
+ }
112
+ return list ;
113
+ } , [ ] ) ;
114
+ }
115
+ if ( _positions && _positions . length === 0 ) {
116
+ _positions = undefined ;
117
+ }
123
118
124
- let _locations ;
125
- if ( positions && source ) {
126
- _locations = positions . map ( pos => getLocation ( source , pos ) ) ;
127
- } else if ( _nodes ) {
128
- _locations = _nodes . reduce ( ( list , node ) => {
129
- if ( node . loc ) {
130
- list . push ( getLocation ( node . loc . source , node . loc . start ) ) ;
119
+ let _locations ;
120
+ if ( positions && source ) {
121
+ _locations = positions . map ( pos => getLocation ( source , pos ) ) ;
122
+ } else if ( _nodes ) {
123
+ _locations = _nodes . reduce ( ( list , node ) => {
124
+ if ( node . loc ) {
125
+ list . push ( getLocation ( node . loc . source , node . loc . start ) ) ;
126
+ }
127
+ return list ;
128
+ } , [ ] ) ;
129
+ }
130
+
131
+ let _extensions = extensions ;
132
+ if ( _extensions == null && originalError != null ) {
133
+ const originalExtensions = originalError . extensions ;
134
+ if ( isObjectLike ( originalExtensions ) ) {
135
+ _extensions = originalExtensions ;
131
136
}
132
- return list ;
133
- } , [ ] ) ;
134
- }
137
+ }
135
138
136
- let _extensions = extensions ;
137
- if ( _extensions == null && originalError != null ) {
138
- const originalExtensions = originalError . extensions ;
139
- if ( isObjectLike ( originalExtensions ) ) {
140
- _extensions = originalExtensions ;
139
+ Object . defineProperties ( ( this : any ) , {
140
+ name : { value : 'GraphQLError' } ,
141
+ message : {
142
+ value : message ,
143
+ // By being enumerable, JSON.stringify will include `message` in the
144
+ // resulting output. This ensures that the simplest possible GraphQL
145
+ // service adheres to the spec.
146
+ enumerable : true ,
147
+ writable : true ,
148
+ } ,
149
+ locations : {
150
+ // Coercing falsy values to undefined ensures they will not be included
151
+ // in JSON.stringify() when not provided.
152
+ value : _locations || undefined ,
153
+ // By being enumerable, JSON.stringify will include `locations` in the
154
+ // resulting output. This ensures that the simplest possible GraphQL
155
+ // service adheres to the spec.
156
+ enumerable : _locations != null ,
157
+ } ,
158
+ path : {
159
+ // Coercing falsy values to undefined ensures they will not be included
160
+ // in JSON.stringify() when not provided.
161
+ value : path || undefined ,
162
+ // By being enumerable, JSON.stringify will include `path` in the
163
+ // resulting output. This ensures that the simplest possible GraphQL
164
+ // service adheres to the spec.
165
+ enumerable : path != null ,
166
+ } ,
167
+ nodes : {
168
+ value : _nodes || undefined ,
169
+ } ,
170
+ source : {
171
+ value : _source || undefined ,
172
+ } ,
173
+ positions : {
174
+ value : _positions || undefined ,
175
+ } ,
176
+ originalError : {
177
+ value : originalError ,
178
+ } ,
179
+ extensions : {
180
+ // Coercing falsy values to undefined ensures they will not be included
181
+ // in JSON.stringify() when not provided.
182
+ value : _extensions || undefined ,
183
+ // By being enumerable, JSON.stringify will include `path` in the
184
+ // resulting output. This ensures that the simplest possible GraphQL
185
+ // service adheres to the spec.
186
+ enumerable : _extensions != null ,
187
+ } ,
188
+ } ) ;
189
+
190
+ // Include (non-enumerable) stack trace.
191
+ if ( originalError && originalError . stack ) {
192
+ Object . defineProperty ( this , 'stack' , {
193
+ value : originalError . stack ,
194
+ writable : true ,
195
+ configurable : true ,
196
+ } ) ;
197
+ return ;
198
+ }
199
+
200
+ /* istanbul ignore next (See: https://github.com/graphql/graphql-js/issues/2317) */
201
+ if ( Error . captureStackTrace ) {
202
+ Error . captureStackTrace ( this , GraphQLError ) ;
203
+ } else {
204
+ Object . defineProperty ( this , 'stack' , {
205
+ value : Error ( ) . stack ,
206
+ writable : true ,
207
+ configurable : true ,
208
+ } ) ;
141
209
}
142
210
}
143
211
144
- Object . defineProperties ( this , {
145
- message : {
146
- value : message ,
147
- // By being enumerable, JSON.stringify will include `message` in the
148
- // resulting output. This ensures that the simplest possible GraphQL
149
- // service adheres to the spec.
150
- enumerable : true ,
151
- writable : true ,
152
- } ,
153
- locations : {
154
- // Coercing falsy values to undefined ensures they will not be included
155
- // in JSON.stringify() when not provided.
156
- value : _locations || undefined ,
157
- // By being enumerable, JSON.stringify will include `locations` in the
158
- // resulting output. This ensures that the simplest possible GraphQL
159
- // service adheres to the spec.
160
- enumerable : _locations != null ,
161
- } ,
162
- path : {
163
- // Coercing falsy values to undefined ensures they will not be included
164
- // in JSON.stringify() when not provided.
165
- value : path || undefined ,
166
- // By being enumerable, JSON.stringify will include `path` in the
167
- // resulting output. This ensures that the simplest possible GraphQL
168
- // service adheres to the spec.
169
- enumerable : path != null ,
170
- } ,
171
- nodes : {
172
- value : _nodes || undefined ,
173
- } ,
174
- source : {
175
- value : _source || undefined ,
176
- } ,
177
- positions : {
178
- value : _positions || undefined ,
179
- } ,
180
- originalError : {
181
- value : originalError ,
182
- } ,
183
- extensions : {
184
- // Coercing falsy values to undefined ensures they will not be included
185
- // in JSON.stringify() when not provided.
186
- value : _extensions || undefined ,
187
- // By being enumerable, JSON.stringify will include `path` in the
188
- // resulting output. This ensures that the simplest possible GraphQL
189
- // service adheres to the spec.
190
- enumerable : _extensions != null ,
191
- } ,
192
- } ) ;
193
-
194
- // Include (non-enumerable) stack trace.
195
- if ( originalError && originalError . stack ) {
196
- Object . defineProperty ( this , 'stack' , {
197
- value : originalError . stack ,
198
- writable : true ,
199
- configurable : true ,
200
- } ) ;
201
- return ;
212
+ toString ( ) : string {
213
+ return printError ( this ) ;
202
214
}
203
215
204
- /* istanbul ignore next (See: https://github.com/graphql/graphql-js/issues/2317) */
205
- if ( Error . captureStackTrace ) {
206
- Error . captureStackTrace ( this , GraphQLError ) ;
207
- } else {
208
- Object . defineProperty ( this , 'stack' , {
209
- value : Error ( ) . stack ,
210
- writable : true ,
211
- configurable : true ,
212
- } ) ;
216
+ // FIXME: workaround to not break chai comparisons, should be remove in v16
217
+ // $FlowFixMe Flow doesn't support computed properties yet
218
+ get [ SYMBOL_TO_STRING_TAG ] ( ) : string {
219
+ return 'Object ';
213
220
}
214
221
}
215
222
216
- ( GraphQLError : any ) . prototype = Object . create ( Error . prototype , {
217
- constructor : { value : GraphQLError } ,
218
- name : { value : 'GraphQLError' } ,
219
- toString : {
220
- value : function toString ( ) {
221
- return printError ( this ) ;
222
- } ,
223
- } ,
224
- } ) ;
225
-
226
223
/**
227
224
* Prints a GraphQLError to a string, representing useful location information
228
225
* about the error's position in the source.
0 commit comments