| import { isObjectLike } from '../jsutils/isObjectLike.mjs'; |
| import { getLocation } from '../language/location.mjs'; |
| import { |
| printLocation, |
| printSourceLocation, |
| } from '../language/printLocation.mjs'; |
|
|
| function toNormalizedOptions(args) { |
| const firstArg = args[0]; |
|
|
| if (firstArg == null || 'kind' in firstArg || 'length' in firstArg) { |
| return { |
| nodes: firstArg, |
| source: args[1], |
| positions: args[2], |
| path: args[3], |
| originalError: args[4], |
| extensions: args[5], |
| }; |
| } |
|
|
| return firstArg; |
| } |
| /** |
| * A GraphQLError describes an Error found during the parse, validate, or |
| * execute phases of performing a GraphQL operation. In addition to a message |
| * and stack trace, it also includes information about the locations in a |
| * GraphQL document and/or execution result that correspond to the Error. |
| */ |
|
|
| export class GraphQLError extends Error { |
| /** |
| * An array of `{ line, column }` locations within the source GraphQL document |
| * which correspond to this error. |
| * |
| * Errors during validation often contain multiple locations, for example to |
| * point out two things with the same name. Errors during execution include a |
| * single location, the field which produced the error. |
| * |
| * Enumerable, and appears in the result of JSON.stringify(). |
| */ |
|
|
| /** |
| * An array describing the JSON-path into the execution response which |
| * corresponds to this error. Only included for errors during execution. |
| * |
| * Enumerable, and appears in the result of JSON.stringify(). |
| */ |
|
|
| /** |
| * An array of GraphQL AST Nodes corresponding to this error. |
| */ |
|
|
| /** |
| * The source GraphQL document for the first location of this error. |
| * |
| * Note that if this Error represents more than one node, the source may not |
| * represent nodes after the first node. |
| */ |
|
|
| /** |
| * An array of character offsets within the source GraphQL document |
| * which correspond to this error. |
| */ |
|
|
| /** |
| * The original error thrown from a field resolver during execution. |
| */ |
|
|
| /** |
| * Extension fields to add to the formatted error. |
| */ |
|
|
| /** |
| * @deprecated Please use the `GraphQLErrorOptions` constructor overload instead. |
| */ |
| constructor(message, ...rawArgs) { |
| var _this$nodes, _nodeLocations$, _ref; |
|
|
| const { nodes, source, positions, path, originalError, extensions } = |
| toNormalizedOptions(rawArgs); |
| super(message); |
| this.name = 'GraphQLError'; |
| this.path = path !== null && path !== void 0 ? path : undefined; |
| this.originalError = |
| originalError !== null && originalError !== void 0 |
| ? originalError |
| : undefined; // Compute list of blame nodes. |
|
|
| this.nodes = undefinedIfEmpty( |
| Array.isArray(nodes) ? nodes : nodes ? [nodes] : undefined, |
| ); |
| const nodeLocations = undefinedIfEmpty( |
| (_this$nodes = this.nodes) === null || _this$nodes === void 0 |
| ? void 0 |
| : _this$nodes.map((node) => node.loc).filter((loc) => loc != null), |
| ); // Compute locations in the source for the given nodes/positions. |
|
|
| this.source = |
| source !== null && source !== void 0 |
| ? source |
| : nodeLocations === null || nodeLocations === void 0 |
| ? void 0 |
| : (_nodeLocations$ = nodeLocations[0]) === null || |
| _nodeLocations$ === void 0 |
| ? void 0 |
| : _nodeLocations$.source; |
| this.positions = |
| positions !== null && positions !== void 0 |
| ? positions |
| : nodeLocations === null || nodeLocations === void 0 |
| ? void 0 |
| : nodeLocations.map((loc) => loc.start); |
| this.locations = |
| positions && source |
| ? positions.map((pos) => getLocation(source, pos)) |
| : nodeLocations === null || nodeLocations === void 0 |
| ? void 0 |
| : nodeLocations.map((loc) => getLocation(loc.source, loc.start)); |
| const originalExtensions = isObjectLike( |
| originalError === null || originalError === void 0 |
| ? void 0 |
| : originalError.extensions, |
| ) |
| ? originalError === null || originalError === void 0 |
| ? void 0 |
| : originalError.extensions |
| : undefined; |
| this.extensions = |
| (_ref = |
| extensions !== null && extensions !== void 0 |
| ? extensions |
| : originalExtensions) !== null && _ref !== void 0 |
| ? _ref |
| : Object.create(null); // Only properties prescribed by the spec should be enumerable. |
| // Keep the rest as non-enumerable. |
|
|
| Object.defineProperties(this, { |
| message: { |
| writable: true, |
| enumerable: true, |
| }, |
| name: { |
| enumerable: false, |
| }, |
| nodes: { |
| enumerable: false, |
| }, |
| source: { |
| enumerable: false, |
| }, |
| positions: { |
| enumerable: false, |
| }, |
| originalError: { |
| enumerable: false, |
| }, |
| }); // Include (non-enumerable) stack trace. |
|
|
| /* c8 ignore start */ |
| // FIXME: https://github.com/graphql/graphql-js/issues/2317 |
|
|
| if ( |
| originalError !== null && |
| originalError !== void 0 && |
| originalError.stack |
| ) { |
| Object.defineProperty(this, 'stack', { |
| value: originalError.stack, |
| writable: true, |
| configurable: true, |
| }); |
| } else if (Error.captureStackTrace) { |
| Error.captureStackTrace(this, GraphQLError); |
| } else { |
| Object.defineProperty(this, 'stack', { |
| value: Error().stack, |
| writable: true, |
| configurable: true, |
| }); |
| } |
| /* c8 ignore stop */ |
| } |
|
|
| get [Symbol.toStringTag]() { |
| return 'GraphQLError'; |
| } |
|
|
| toString() { |
| let output = this.message; |
|
|
| if (this.nodes) { |
| for (const node of this.nodes) { |
| if (node.loc) { |
| output += '\n\n' + printLocation(node.loc); |
| } |
| } |
| } else if (this.source && this.locations) { |
| for (const location of this.locations) { |
| output += '\n\n' + printSourceLocation(this.source, location); |
| } |
| } |
|
|
| return output; |
| } |
|
|
| toJSON() { |
| const formattedError = { |
| message: this.message, |
| }; |
|
|
| if (this.locations != null) { |
| formattedError.locations = this.locations; |
| } |
|
|
| if (this.path != null) { |
| formattedError.path = this.path; |
| } |
|
|
| if (this.extensions != null && Object.keys(this.extensions).length > 0) { |
| formattedError.extensions = this.extensions; |
| } |
|
|
| return formattedError; |
| } |
| } |
|
|
| function undefinedIfEmpty(array) { |
| return array === undefined || array.length === 0 ? undefined : array; |
| } |
| /** |
| * See: https://spec.graphql.org/draft/#sec-Errors |
| */ |
|
|
| /** |
| * Prints a GraphQLError to a string, representing useful location information |
| * about the error's position in the source. |
| * |
| * @deprecated Please use `error.toString` instead. Will be removed in v17 |
| */ |
| export function printError(error) { |
| return error.toString(); |
| } |
| /** |
| * Given a GraphQLError, format it according to the rules described by the |
| * Response Format, Errors section of the GraphQL Specification. |
| * |
| * @deprecated Please use `error.toJSON` instead. Will be removed in v17 |
| */ |
|
|
| export function formatError(error) { |
| return error.toJSON(); |
| } |