You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
7.0 KiB
253 lines
7.0 KiB
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(); |
|
}
|
|
|