Skip to content

Commit 82900fa

Browse files
GraphQLError: use enumerable properties (#3311)
1 parent 01fa868 commit 82900fa

File tree

1 file changed

+34
-83
lines changed

1 file changed

+34
-83
lines changed

src/error/GraphQLError.ts

+34-83
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,44 @@ export class GraphQLError extends Error {
2424
*
2525
* Enumerable, and appears in the result of JSON.stringify().
2626
*/
27-
readonly locations?: ReadonlyArray<SourceLocation>;
27+
readonly locations: ReadonlyArray<SourceLocation> | undefined;
2828

2929
/**
3030
* An array describing the JSON-path into the execution response which
3131
* corresponds to this error. Only included for errors during execution.
3232
*
3333
* Enumerable, and appears in the result of JSON.stringify().
3434
*/
35-
readonly path?: ReadonlyArray<string | number>;
35+
readonly path: ReadonlyArray<string | number> | undefined;
3636

3737
/**
3838
* An array of GraphQL AST Nodes corresponding to this error.
3939
*/
40-
readonly nodes?: ReadonlyArray<ASTNode>;
40+
readonly nodes: ReadonlyArray<ASTNode> | undefined;
4141

4242
/**
4343
* The source GraphQL document for the first location of this error.
4444
*
4545
* Note that if this Error represents more than one node, the source may not
4646
* represent nodes after the first node.
4747
*/
48-
readonly source?: Source;
48+
readonly source: Source | undefined;
4949

5050
/**
5151
* An array of character offsets within the source GraphQL document
5252
* which correspond to this error.
5353
*/
54-
readonly positions?: ReadonlyArray<number>;
54+
readonly positions: ReadonlyArray<number> | undefined;
5555

5656
/**
5757
* The original error thrown from a field resolver during execution.
5858
*/
59-
readonly originalError: Maybe<Error>;
59+
readonly originalError: Error | undefined;
6060

6161
/**
6262
* Extension fields to add to the formatted error.
6363
*/
64-
readonly extensions?: { [key: string]: unknown };
64+
readonly extensions: { [key: string]: unknown } | undefined;
6565

6666
constructor(
6767
message: string,
@@ -74,8 +74,12 @@ export class GraphQLError extends Error {
7474
) {
7575
super(message);
7676

77+
this.name = 'GraphQLError';
78+
this.path = path ?? undefined;
79+
this.originalError = originalError ?? undefined;
80+
7781
// Compute list of blame nodes.
78-
const _nodes = Array.isArray(nodes)
82+
this.nodes = Array.isArray(nodes)
7983
? nodes.length !== 0
8084
? nodes
8185
: undefined
@@ -84,96 +88,43 @@ export class GraphQLError extends Error {
8488
: undefined;
8589

8690
// Compute locations in the source for the given nodes/positions.
87-
let _source = source;
88-
if (!_source && _nodes) {
89-
_source = _nodes[0].loc?.source;
91+
this.source = source ?? undefined;
92+
if (!this.source && this.nodes) {
93+
this.source = this.nodes[0].loc?.source;
9094
}
9195

92-
let _positions;
9396
if (positions) {
94-
_positions = positions;
95-
} else if (_nodes) {
96-
_positions = [];
97-
for (const node of _nodes) {
97+
this.positions = positions;
98+
} else if (this.nodes) {
99+
const positionsFromNodes = [];
100+
for (const node of this.nodes) {
98101
if (node.loc) {
99-
_positions.push(node.loc.start);
102+
positionsFromNodes.push(node.loc.start);
100103
}
101104
}
105+
this.positions = positionsFromNodes;
102106
}
103-
if (_positions && _positions.length === 0) {
104-
_positions = undefined;
107+
if (this.positions && this.positions.length === 0) {
108+
this.positions = undefined;
105109
}
106110

107-
let _locations;
108111
if (positions && source) {
109-
_locations = positions.map((pos) => getLocation(source, pos));
110-
} else if (_nodes) {
111-
_locations = [];
112-
for (const node of _nodes) {
112+
this.locations = positions.map((pos) => getLocation(source, pos));
113+
} else if (this.nodes) {
114+
const locationsFromNodes = [];
115+
for (const node of this.nodes) {
113116
if (node.loc) {
114-
_locations.push(getLocation(node.loc.source, node.loc.start));
117+
locationsFromNodes.push(getLocation(node.loc.source, node.loc.start));
115118
}
116119
}
120+
this.locations = locationsFromNodes;
117121
}
118122

119-
let _extensions = extensions;
120-
if (_extensions == null && originalError != null) {
121-
const originalExtensions = originalError.extensions;
122-
if (isObjectLike(originalExtensions)) {
123-
_extensions = originalExtensions;
124-
}
125-
}
126-
127-
Object.defineProperties(this, {
128-
name: { value: 'GraphQLError' },
129-
message: {
130-
value: message,
131-
// By being enumerable, JSON.stringify will include `message` in the
132-
// resulting output. This ensures that the simplest possible GraphQL
133-
// service adheres to the spec.
134-
enumerable: true,
135-
writable: true,
136-
},
137-
locations: {
138-
// Coercing falsy values to undefined ensures they will not be included
139-
// in JSON.stringify() when not provided.
140-
value: _locations ?? undefined,
141-
// By being enumerable, JSON.stringify will include `locations` in the
142-
// resulting output. This ensures that the simplest possible GraphQL
143-
// service adheres to the spec.
144-
enumerable: _locations != null,
145-
},
146-
path: {
147-
// Coercing falsy values to undefined ensures they will not be included
148-
// in JSON.stringify() when not provided.
149-
value: path ?? undefined,
150-
// By being enumerable, JSON.stringify will include `path` in the
151-
// resulting output. This ensures that the simplest possible GraphQL
152-
// service adheres to the spec.
153-
enumerable: path != null,
154-
},
155-
nodes: {
156-
value: _nodes ?? undefined,
157-
},
158-
source: {
159-
value: _source ?? undefined,
160-
},
161-
positions: {
162-
value: _positions ?? undefined,
163-
},
164-
originalError: {
165-
value: originalError,
166-
},
167-
extensions: {
168-
// Coercing falsy values to undefined ensures they will not be included
169-
// in JSON.stringify() when not provided.
170-
value: _extensions ?? undefined,
171-
// By being enumerable, JSON.stringify will include `path` in the
172-
// resulting output. This ensures that the simplest possible GraphQL
173-
// service adheres to the spec.
174-
enumerable: _extensions != null,
175-
},
176-
});
123+
const originalExtensions = isObjectLike(originalError?.extensions)
124+
? originalError?.extensions
125+
: undefined;
126+
// TODO: merge `extensions` and `originalExtensions`
127+
this.extensions = extensions ?? originalExtensions;
177128

178129
// Include (non-enumerable) stack trace.
179130
if (originalError?.stack) {

0 commit comments

Comments
 (0)