|
1 | 1 | import { isObjectLike } from '../jsutils/isObjectLike';
|
2 | 2 | import type { Maybe } from '../jsutils/Maybe';
|
3 | 3 |
|
4 |
| -import type { ASTNode } from '../language/ast'; |
| 4 | +import type { ASTNode, Location } from '../language/ast'; |
5 | 5 | import type { Source } from '../language/source';
|
6 | 6 | import type { SourceLocation } from '../language/location';
|
7 | 7 | import { getLocation } from '../language/location';
|
@@ -92,65 +92,40 @@ export class GraphQLError extends Error {
|
92 | 92 | this.originalError = originalError ?? undefined;
|
93 | 93 |
|
94 | 94 | // Compute list of blame nodes.
|
95 |
| - this.nodes = Array.isArray(nodes) |
96 |
| - ? nodes.length !== 0 |
97 |
| - ? nodes |
98 |
| - : undefined |
99 |
| - : nodes |
100 |
| - ? [nodes] |
101 |
| - : undefined; |
| 95 | + this.nodes = undefinedIfEmpty( |
| 96 | + Array.isArray(nodes) ? nodes : nodes ? [nodes] : undefined, |
| 97 | + ); |
| 98 | + |
| 99 | + const nodeLocations = undefinedIfEmpty( |
| 100 | + this.nodes |
| 101 | + ?.map((node) => node.loc) |
| 102 | + .filter((loc): loc is Location => loc != null), |
| 103 | + ); |
102 | 104 |
|
103 | 105 | // Compute locations in the source for the given nodes/positions.
|
104 |
| - this.source = source ?? undefined; |
105 |
| - if (!this.source && this.nodes) { |
106 |
| - this.source = this.nodes[0].loc?.source; |
107 |
| - } |
| 106 | + this.source = source ?? nodeLocations?.[0]?.source; |
108 | 107 |
|
109 |
| - if (positions) { |
110 |
| - this.positions = positions; |
111 |
| - } else if (this.nodes) { |
112 |
| - const positionsFromNodes = []; |
113 |
| - for (const node of this.nodes) { |
114 |
| - if (node.loc) { |
115 |
| - positionsFromNodes.push(node.loc.start); |
116 |
| - } |
117 |
| - } |
118 |
| - this.positions = positionsFromNodes; |
119 |
| - } |
120 |
| - if (this.positions && this.positions.length === 0) { |
121 |
| - this.positions = undefined; |
122 |
| - } |
| 108 | + this.positions = positions ?? nodeLocations?.map((loc) => loc.start); |
123 | 109 |
|
124 |
| - if (positions && source) { |
125 |
| - this.locations = positions.map((pos) => getLocation(source, pos)); |
126 |
| - } else if (this.nodes) { |
127 |
| - const locationsFromNodes = []; |
128 |
| - for (const node of this.nodes) { |
129 |
| - if (node.loc) { |
130 |
| - locationsFromNodes.push(getLocation(node.loc.source, node.loc.start)); |
131 |
| - } |
132 |
| - } |
133 |
| - this.locations = locationsFromNodes; |
134 |
| - } |
| 110 | + this.locations = |
| 111 | + positions && source |
| 112 | + ? positions.map((pos) => getLocation(source, pos)) |
| 113 | + : nodeLocations?.map((loc) => getLocation(loc.source, loc.start)); |
135 | 114 |
|
136 | 115 | const originalExtensions = isObjectLike(originalError?.extensions)
|
137 | 116 | ? originalError?.extensions
|
138 | 117 | : undefined;
|
139 |
| - // TODO: merge `extensions` and `originalExtensions` |
140 | 118 | this.extensions = extensions ?? originalExtensions ?? Object.create(null);
|
141 | 119 |
|
142 | 120 | // Include (non-enumerable) stack trace.
|
| 121 | + // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317') |
143 | 122 | if (originalError?.stack) {
|
144 | 123 | Object.defineProperty(this, 'stack', {
|
145 | 124 | value: originalError.stack,
|
146 | 125 | writable: true,
|
147 | 126 | configurable: true,
|
148 | 127 | });
|
149 |
| - return; |
150 |
| - } |
151 |
| - |
152 |
| - // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317') |
153 |
| - if (Error.captureStackTrace) { |
| 128 | + } else if (Error.captureStackTrace) { |
154 | 129 | Error.captureStackTrace(this, GraphQLError);
|
155 | 130 | } else {
|
156 | 131 | Object.defineProperty(this, 'stack', {
|
@@ -208,6 +183,12 @@ export class GraphQLError extends Error {
|
208 | 183 | }
|
209 | 184 | }
|
210 | 185 |
|
| 186 | +function undefinedIfEmpty<T>( |
| 187 | + array: Array<T> | undefined, |
| 188 | +): Array<T> | undefined { |
| 189 | + return array === undefined || array.length === 0 ? undefined : array; |
| 190 | +} |
| 191 | + |
211 | 192 | /**
|
212 | 193 | * See: https://spec.graphql.org/draft/#sec-Errors
|
213 | 194 | */
|
|
0 commit comments