Skip to content

Commit a9bf2f5

Browse files
GraphQLError: convert to ES6 class (#2369)
1 parent 1d85e45 commit a9bf2f5

File tree

3 files changed

+144
-140
lines changed

3 files changed

+144
-140
lines changed

.babelrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
"presets": [["@babel/preset-env", { "modules": false }]]
2323
}
2424
}
25+
},
26+
{
27+
"include": "src/error/GraphQLError.js",
28+
"plugins": [
29+
["@babel/plugin-transform-classes", { "loose": false }]
30+
]
2531
}
2632
]
2733
}

cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"jsutils",
99
"tsutils",
1010
"noflow",
11+
"flowlint",
1112

1213
// Different names used inside tests
1314
"Skywalker",

src/error/GraphQLError.js

Lines changed: 137 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// @flow strict
22

3+
// FIXME:
4+
// flowlint uninitialized-instance-property:off
5+
36
import isObjectLike from '../jsutils/isObjectLike';
7+
import { SYMBOL_TO_STRING_TAG } from '../polyfills/symbols';
48

59
import { type ASTNode } from '../language/ast';
610
import { type Source } from '../language/source';
@@ -13,17 +17,7 @@ import { printLocation, printSourceLocation } from '../language/printLocation';
1317
* and stack trace, it also includes information about the locations in a
1418
* GraphQL document and/or execution result that correspond to the Error.
1519
*/
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 {
2721
/**
2822
* A message describing the Error for debugging purposes.
2923
*
@@ -81,148 +75,151 @@ declare class GraphQLError extends Error {
8175
* Extension fields to add to the formatted error.
8276
*/
8377
+extensions: { [key: string]: mixed, ... } | void;
84-
}
8578

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+
}
110105

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+
}
123118

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;
131136
}
132-
return list;
133-
}, []);
134-
}
137+
}
135138

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+
});
141209
}
142210
}
143211

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);
202214
}
203215

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';
213220
}
214221
}
215222

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-
226223
/**
227224
* Prints a GraphQLError to a string, representing useful location information
228225
* about the error's position in the source.

0 commit comments

Comments
 (0)