254 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 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();
 | |
| }
 |