|
4 | 4 | import isObjectLike from '../jsutils/isObjectLike';
|
5 | 5 | import { SYMBOL_TO_STRING_TAG } from '../polyfills/symbols';
|
6 | 6 |
|
7 |
| -import type { ASTNode } from '../language/ast'; |
| 7 | +import type { ASTNode, Location } from '../language/ast'; |
8 | 8 | import type { Source } from '../language/source';
|
9 | 9 | import type { SourceLocation } from '../language/location';
|
10 | 10 | import { getLocation } from '../language/location';
|
@@ -87,51 +87,33 @@ export class GraphQLError extends Error {
|
87 | 87 | super(message);
|
88 | 88 |
|
89 | 89 | // Compute list of blame nodes.
|
90 |
| - const _nodes = Array.isArray(nodes) |
91 |
| - ? nodes.length !== 0 |
92 |
| - ? nodes |
93 |
| - : undefined |
94 |
| - : nodes |
95 |
| - ? [nodes] |
96 |
| - : undefined; |
| 90 | + const _nodes = undefinedIfEmpty( |
| 91 | + Array.isArray(nodes) ? nodes : nodes ? [nodes] : undefined, |
| 92 | + ); |
| 93 | + |
| 94 | + let nodeLocations = []; |
| 95 | + for (const { loc } of (_nodes ?? [])) { |
| 96 | + if (loc != null) { |
| 97 | + nodeLocations.push(loc); |
| 98 | + } |
| 99 | + } |
| 100 | + nodeLocations = undefinedIfEmpty(nodeLocations); |
97 | 101 |
|
98 | 102 | // Compute locations in the source for the given nodes/positions.
|
99 |
| - let _source = source; |
100 |
| - if (!_source && _nodes) { |
101 |
| - _source = _nodes[0].loc?.source; |
102 |
| - } |
| 103 | + const _source = source ?? nodeLocations?.[0].source; |
103 | 104 |
|
104 |
| - let _positions = positions; |
105 |
| - if (!_positions && _nodes) { |
106 |
| - _positions = _nodes.reduce((list, node) => { |
107 |
| - if (node.loc) { |
108 |
| - list.push(node.loc.start); |
109 |
| - } |
110 |
| - return list; |
111 |
| - }, []); |
112 |
| - } |
113 |
| - if (_positions && _positions.length === 0) { |
114 |
| - _positions = undefined; |
115 |
| - } |
| 105 | + const _positions = positions ?? nodeLocations?.map((loc) => loc.start); |
116 | 106 |
|
117 |
| - let _locations; |
118 |
| - if (positions && source) { |
119 |
| - _locations = positions.map((pos) => getLocation(source, pos)); |
120 |
| - } else if (_nodes) { |
121 |
| - _locations = _nodes.reduce((list, node) => { |
122 |
| - if (node.loc) { |
123 |
| - list.push(getLocation(node.loc.source, node.loc.start)); |
124 |
| - } |
125 |
| - return list; |
126 |
| - }, []); |
127 |
| - } |
| 107 | + const _locations = |
| 108 | + positions && source |
| 109 | + ? positions.map((pos) => getLocation(source, pos)) |
| 110 | + : nodeLocations?.map((loc) => getLocation(loc.source, loc.start)); |
128 | 111 |
|
129 |
| - let _extensions = extensions; |
130 |
| - if (_extensions == null && originalError != null) { |
131 |
| - const originalExtensions = originalError.extensions; |
132 |
| - if (isObjectLike(originalExtensions)) { |
133 |
| - _extensions = originalExtensions; |
134 |
| - } |
| 112 | + let _extensions = extensions ?? undefined; |
| 113 | + |
| 114 | + let originalExtensions = originalError?.extensions; |
| 115 | + if (isObjectLike(originalExtensions)) { |
| 116 | + _extensions = originalExtensions; |
135 | 117 | }
|
136 | 118 |
|
137 | 119 | Object.defineProperties((this: any), {
|
@@ -218,6 +200,12 @@ export class GraphQLError extends Error {
|
218 | 200 | }
|
219 | 201 | }
|
220 | 202 |
|
| 203 | +function undefinedIfEmpty<T>( |
| 204 | + array: $ReadOnlyArray<T> | void, |
| 205 | +): $ReadOnlyArray<T> | void { |
| 206 | + return array === undefined || array.length === 0 ? undefined : array; |
| 207 | +} |
| 208 | + |
221 | 209 | /**
|
222 | 210 | * Prints a GraphQLError to a string, representing useful location information
|
223 | 211 | * about the error's position in the source.
|
|
0 commit comments