GraphQLError.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true,
  4. });
  5. exports.GraphQLError = void 0;
  6. exports.formatError = formatError;
  7. exports.printError = printError;
  8. var _isObjectLike = require('../jsutils/isObjectLike.js');
  9. var _location = require('../language/location.js');
  10. var _printLocation = require('../language/printLocation.js');
  11. function toNormalizedOptions(args) {
  12. const firstArg = args[0];
  13. if (firstArg == null || 'kind' in firstArg || 'length' in firstArg) {
  14. return {
  15. nodes: firstArg,
  16. source: args[1],
  17. positions: args[2],
  18. path: args[3],
  19. originalError: args[4],
  20. extensions: args[5],
  21. };
  22. }
  23. return firstArg;
  24. }
  25. /**
  26. * A GraphQLError describes an Error found during the parse, validate, or
  27. * execute phases of performing a GraphQL operation. In addition to a message
  28. * and stack trace, it also includes information about the locations in a
  29. * GraphQL document and/or execution result that correspond to the Error.
  30. */
  31. class GraphQLError extends Error {
  32. /**
  33. * An array of `{ line, column }` locations within the source GraphQL document
  34. * which correspond to this error.
  35. *
  36. * Errors during validation often contain multiple locations, for example to
  37. * point out two things with the same name. Errors during execution include a
  38. * single location, the field which produced the error.
  39. *
  40. * Enumerable, and appears in the result of JSON.stringify().
  41. */
  42. /**
  43. * An array describing the JSON-path into the execution response which
  44. * corresponds to this error. Only included for errors during execution.
  45. *
  46. * Enumerable, and appears in the result of JSON.stringify().
  47. */
  48. /**
  49. * An array of GraphQL AST Nodes corresponding to this error.
  50. */
  51. /**
  52. * The source GraphQL document for the first location of this error.
  53. *
  54. * Note that if this Error represents more than one node, the source may not
  55. * represent nodes after the first node.
  56. */
  57. /**
  58. * An array of character offsets within the source GraphQL document
  59. * which correspond to this error.
  60. */
  61. /**
  62. * The original error thrown from a field resolver during execution.
  63. */
  64. /**
  65. * Extension fields to add to the formatted error.
  66. */
  67. /**
  68. * @deprecated Please use the `GraphQLErrorOptions` constructor overload instead.
  69. */
  70. constructor(message, ...rawArgs) {
  71. var _this$nodes, _nodeLocations$, _ref;
  72. const { nodes, source, positions, path, originalError, extensions } =
  73. toNormalizedOptions(rawArgs);
  74. super(message);
  75. this.name = 'GraphQLError';
  76. this.path = path !== null && path !== void 0 ? path : undefined;
  77. this.originalError =
  78. originalError !== null && originalError !== void 0
  79. ? originalError
  80. : undefined; // Compute list of blame nodes.
  81. this.nodes = undefinedIfEmpty(
  82. Array.isArray(nodes) ? nodes : nodes ? [nodes] : undefined,
  83. );
  84. const nodeLocations = undefinedIfEmpty(
  85. (_this$nodes = this.nodes) === null || _this$nodes === void 0
  86. ? void 0
  87. : _this$nodes.map((node) => node.loc).filter((loc) => loc != null),
  88. ); // Compute locations in the source for the given nodes/positions.
  89. this.source =
  90. source !== null && source !== void 0
  91. ? source
  92. : nodeLocations === null || nodeLocations === void 0
  93. ? void 0
  94. : (_nodeLocations$ = nodeLocations[0]) === null ||
  95. _nodeLocations$ === void 0
  96. ? void 0
  97. : _nodeLocations$.source;
  98. this.positions =
  99. positions !== null && positions !== void 0
  100. ? positions
  101. : nodeLocations === null || nodeLocations === void 0
  102. ? void 0
  103. : nodeLocations.map((loc) => loc.start);
  104. this.locations =
  105. positions && source
  106. ? positions.map((pos) => (0, _location.getLocation)(source, pos))
  107. : nodeLocations === null || nodeLocations === void 0
  108. ? void 0
  109. : nodeLocations.map((loc) =>
  110. (0, _location.getLocation)(loc.source, loc.start),
  111. );
  112. const originalExtensions = (0, _isObjectLike.isObjectLike)(
  113. originalError === null || originalError === void 0
  114. ? void 0
  115. : originalError.extensions,
  116. )
  117. ? originalError === null || originalError === void 0
  118. ? void 0
  119. : originalError.extensions
  120. : undefined;
  121. this.extensions =
  122. (_ref =
  123. extensions !== null && extensions !== void 0
  124. ? extensions
  125. : originalExtensions) !== null && _ref !== void 0
  126. ? _ref
  127. : Object.create(null); // Only properties prescribed by the spec should be enumerable.
  128. // Keep the rest as non-enumerable.
  129. Object.defineProperties(this, {
  130. message: {
  131. writable: true,
  132. enumerable: true,
  133. },
  134. name: {
  135. enumerable: false,
  136. },
  137. nodes: {
  138. enumerable: false,
  139. },
  140. source: {
  141. enumerable: false,
  142. },
  143. positions: {
  144. enumerable: false,
  145. },
  146. originalError: {
  147. enumerable: false,
  148. },
  149. }); // Include (non-enumerable) stack trace.
  150. /* c8 ignore start */
  151. // FIXME: https://github.com/graphql/graphql-js/issues/2317
  152. if (
  153. originalError !== null &&
  154. originalError !== void 0 &&
  155. originalError.stack
  156. ) {
  157. Object.defineProperty(this, 'stack', {
  158. value: originalError.stack,
  159. writable: true,
  160. configurable: true,
  161. });
  162. } else if (Error.captureStackTrace) {
  163. Error.captureStackTrace(this, GraphQLError);
  164. } else {
  165. Object.defineProperty(this, 'stack', {
  166. value: Error().stack,
  167. writable: true,
  168. configurable: true,
  169. });
  170. }
  171. /* c8 ignore stop */
  172. }
  173. get [Symbol.toStringTag]() {
  174. return 'GraphQLError';
  175. }
  176. toString() {
  177. let output = this.message;
  178. if (this.nodes) {
  179. for (const node of this.nodes) {
  180. if (node.loc) {
  181. output += '\n\n' + (0, _printLocation.printLocation)(node.loc);
  182. }
  183. }
  184. } else if (this.source && this.locations) {
  185. for (const location of this.locations) {
  186. output +=
  187. '\n\n' +
  188. (0, _printLocation.printSourceLocation)(this.source, location);
  189. }
  190. }
  191. return output;
  192. }
  193. toJSON() {
  194. const formattedError = {
  195. message: this.message,
  196. };
  197. if (this.locations != null) {
  198. formattedError.locations = this.locations;
  199. }
  200. if (this.path != null) {
  201. formattedError.path = this.path;
  202. }
  203. if (this.extensions != null && Object.keys(this.extensions).length > 0) {
  204. formattedError.extensions = this.extensions;
  205. }
  206. return formattedError;
  207. }
  208. }
  209. exports.GraphQLError = GraphQLError;
  210. function undefinedIfEmpty(array) {
  211. return array === undefined || array.length === 0 ? undefined : array;
  212. }
  213. /**
  214. * See: https://spec.graphql.org/draft/#sec-Errors
  215. */
  216. /**
  217. * Prints a GraphQLError to a string, representing useful location information
  218. * about the error's position in the source.
  219. *
  220. * @deprecated Please use `error.toString` instead. Will be removed in v17
  221. */
  222. function printError(error) {
  223. return error.toString();
  224. }
  225. /**
  226. * Given a GraphQLError, format it according to the rules described by the
  227. * Response Format, Errors section of the GraphQL Specification.
  228. *
  229. * @deprecated Please use `error.toJSON` instead. Will be removed in v17
  230. */
  231. function formatError(error) {
  232. return error.toJSON();
  233. }