Initial Save
This commit is contained in:
21
node_modules/apollo-server-errors/LICENSE
generated
vendored
Normal file
21
node_modules/apollo-server-errors/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Apollo Graph, Inc. (Formerly Meteor Development Group, Inc.)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
50
node_modules/apollo-server-errors/dist/index.d.ts
generated
vendored
Normal file
50
node_modules/apollo-server-errors/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { GraphQLError, GraphQLFormattedError } from 'graphql';
|
||||
export declare class ApolloError extends Error implements GraphQLError {
|
||||
extensions: Record<string, any>;
|
||||
readonly name: any;
|
||||
readonly locations: any;
|
||||
readonly path: any;
|
||||
readonly source: any;
|
||||
readonly positions: any;
|
||||
readonly nodes: any;
|
||||
originalError: any;
|
||||
[key: string]: any;
|
||||
constructor(message: string, code?: string, extensions?: Record<string, any>);
|
||||
}
|
||||
export declare function toApolloError(error: Error & {
|
||||
extensions?: Record<string, any>;
|
||||
}, code?: string): Error & {
|
||||
extensions: Record<string, any>;
|
||||
};
|
||||
export interface ErrorOptions {
|
||||
code?: string;
|
||||
errorClass?: new (message: string) => ApolloError;
|
||||
}
|
||||
export declare function fromGraphQLError(error: GraphQLError, options?: ErrorOptions): ApolloError;
|
||||
export declare class SyntaxError extends ApolloError {
|
||||
constructor(message: string);
|
||||
}
|
||||
export declare class ValidationError extends ApolloError {
|
||||
constructor(message: string);
|
||||
}
|
||||
export declare class AuthenticationError extends ApolloError {
|
||||
constructor(message: string);
|
||||
}
|
||||
export declare class ForbiddenError extends ApolloError {
|
||||
constructor(message: string);
|
||||
}
|
||||
export declare class PersistedQueryNotFoundError extends ApolloError {
|
||||
constructor();
|
||||
}
|
||||
export declare class PersistedQueryNotSupportedError extends ApolloError {
|
||||
constructor();
|
||||
}
|
||||
export declare class UserInputError extends ApolloError {
|
||||
constructor(message: string, properties?: Record<string, any>);
|
||||
}
|
||||
export declare function formatApolloErrors(errors: ReadonlyArray<Error>, options?: {
|
||||
formatter?: (error: GraphQLError) => GraphQLFormattedError;
|
||||
debug?: boolean;
|
||||
}): Array<ApolloError>;
|
||||
export declare function hasPersistedQueryError(errors: Array<Error>): boolean;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/apollo-server-errors/dist/index.d.ts.map
generated
vendored
Normal file
1
node_modules/apollo-server-errors/dist/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE9D,qBAAa,WAAY,SAAQ,KAAM,YAAW,YAAY;IACrD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,QAAQ,CAAC,IAAI,MAAC;IACd,QAAQ,CAAC,SAAS,MAAC;IACnB,QAAQ,CAAC,IAAI,MAAC;IACd,QAAQ,CAAC,MAAM,MAAC;IAChB,QAAQ,CAAC,SAAS,MAAC;IACnB,QAAQ,CAAC,KAAK,MAAC;IACR,aAAa,MAAC;IAErB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;gBAGjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAsCnC;AAkED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,EACnD,IAAI,GAAE,MAAgC,GACrC,KAAK,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAQ7C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,UAAU,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,KAAK,WAAW,CAAC;CACnD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,eA8B3E;AAED,qBAAa,WAAY,SAAQ,WAAW;gBAC9B,OAAO,EAAE,MAAM;CAK5B;AAED,qBAAa,eAAgB,SAAQ,WAAW;gBAClC,OAAO,EAAE,MAAM;CAK5B;AAED,qBAAa,mBAAoB,SAAQ,WAAW;gBACtC,OAAO,EAAE,MAAM;CAK5B;AAED,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,EAAE,MAAM;CAK5B;AAED,qBAAa,2BAA4B,SAAQ,WAAW;;CAQ3D;AAED,qBAAa,+BAAgC,SAAQ,WAAW;;CAQ/D;AAED,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAK9D;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,EAC5B,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,qBAAqB,CAAC;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACA,KAAK,CAAC,WAAW,CAAC,CA4DpB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAQpE"}
|
||||
189
node_modules/apollo-server-errors/dist/index.js
generated
vendored
Normal file
189
node_modules/apollo-server-errors/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.hasPersistedQueryError = exports.formatApolloErrors = exports.UserInputError = exports.PersistedQueryNotSupportedError = exports.PersistedQueryNotFoundError = exports.ForbiddenError = exports.AuthenticationError = exports.ValidationError = exports.SyntaxError = exports.fromGraphQLError = exports.toApolloError = exports.ApolloError = void 0;
|
||||
const graphql_1 = require("graphql");
|
||||
class ApolloError extends Error {
|
||||
constructor(message, code, extensions) {
|
||||
super(message);
|
||||
if (extensions) {
|
||||
Object.keys(extensions)
|
||||
.filter(keyName => keyName !== 'message' && keyName !== 'extensions')
|
||||
.forEach(key => {
|
||||
this[key] = extensions[key];
|
||||
});
|
||||
}
|
||||
if (!this.name) {
|
||||
Object.defineProperty(this, 'name', { value: 'ApolloError' });
|
||||
}
|
||||
const userProvidedExtensions = (extensions && extensions.extensions) || null;
|
||||
this.extensions = Object.assign(Object.assign(Object.assign({}, extensions), userProvidedExtensions), { code });
|
||||
}
|
||||
}
|
||||
exports.ApolloError = ApolloError;
|
||||
function enrichError(error, debug = false) {
|
||||
const expanded = Object.create(Object.getPrototypeOf(error), {
|
||||
name: {
|
||||
value: error.name,
|
||||
},
|
||||
message: {
|
||||
value: error.message,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
},
|
||||
locations: {
|
||||
value: error.locations || undefined,
|
||||
enumerable: true,
|
||||
},
|
||||
path: {
|
||||
value: error.path || undefined,
|
||||
enumerable: true,
|
||||
},
|
||||
nodes: {
|
||||
value: error.nodes || undefined,
|
||||
},
|
||||
source: {
|
||||
value: error.source || undefined,
|
||||
},
|
||||
positions: {
|
||||
value: error.positions || undefined,
|
||||
},
|
||||
originalError: {
|
||||
value: error.originalError,
|
||||
},
|
||||
});
|
||||
expanded.extensions = Object.assign(Object.assign({}, error.extensions), { code: (error.extensions && error.extensions.code) || 'INTERNAL_SERVER_ERROR', exception: Object.assign(Object.assign({}, (error.extensions && error.extensions.exception)), error.originalError) });
|
||||
delete expanded.extensions.exception.extensions;
|
||||
if (debug && !expanded.extensions.exception.stacktrace) {
|
||||
expanded.extensions.exception.stacktrace =
|
||||
(error.originalError &&
|
||||
error.originalError.stack &&
|
||||
error.originalError.stack.split('\n')) ||
|
||||
(error.stack && error.stack.split('\n'));
|
||||
}
|
||||
if (Object.keys(expanded.extensions.exception).length === 0) {
|
||||
delete expanded.extensions.exception;
|
||||
}
|
||||
return expanded;
|
||||
}
|
||||
function toApolloError(error, code = 'INTERNAL_SERVER_ERROR') {
|
||||
let err = error;
|
||||
if (err.extensions) {
|
||||
err.extensions.code = code;
|
||||
}
|
||||
else {
|
||||
err.extensions = { code };
|
||||
}
|
||||
return err;
|
||||
}
|
||||
exports.toApolloError = toApolloError;
|
||||
function fromGraphQLError(error, options) {
|
||||
const copy = options && options.errorClass
|
||||
? new options.errorClass(error.message)
|
||||
: new ApolloError(error.message);
|
||||
Object.keys(error).forEach(key => {
|
||||
copy[key] = error[key];
|
||||
});
|
||||
copy.extensions = Object.assign(Object.assign({}, copy.extensions), error.extensions);
|
||||
if (!copy.extensions.code) {
|
||||
copy.extensions.code = (options && options.code) || 'INTERNAL_SERVER_ERROR';
|
||||
}
|
||||
Object.defineProperty(copy, 'originalError', { value: {} });
|
||||
Object.getOwnPropertyNames(error).forEach(key => {
|
||||
Object.defineProperty(copy.originalError, key, { value: error[key] });
|
||||
});
|
||||
return copy;
|
||||
}
|
||||
exports.fromGraphQLError = fromGraphQLError;
|
||||
class SyntaxError extends ApolloError {
|
||||
constructor(message) {
|
||||
super(message, 'GRAPHQL_PARSE_FAILED');
|
||||
Object.defineProperty(this, 'name', { value: 'SyntaxError' });
|
||||
}
|
||||
}
|
||||
exports.SyntaxError = SyntaxError;
|
||||
class ValidationError extends ApolloError {
|
||||
constructor(message) {
|
||||
super(message, 'GRAPHQL_VALIDATION_FAILED');
|
||||
Object.defineProperty(this, 'name', { value: 'ValidationError' });
|
||||
}
|
||||
}
|
||||
exports.ValidationError = ValidationError;
|
||||
class AuthenticationError extends ApolloError {
|
||||
constructor(message) {
|
||||
super(message, 'UNAUTHENTICATED');
|
||||
Object.defineProperty(this, 'name', { value: 'AuthenticationError' });
|
||||
}
|
||||
}
|
||||
exports.AuthenticationError = AuthenticationError;
|
||||
class ForbiddenError extends ApolloError {
|
||||
constructor(message) {
|
||||
super(message, 'FORBIDDEN');
|
||||
Object.defineProperty(this, 'name', { value: 'ForbiddenError' });
|
||||
}
|
||||
}
|
||||
exports.ForbiddenError = ForbiddenError;
|
||||
class PersistedQueryNotFoundError extends ApolloError {
|
||||
constructor() {
|
||||
super('PersistedQueryNotFound', 'PERSISTED_QUERY_NOT_FOUND');
|
||||
Object.defineProperty(this, 'name', {
|
||||
value: 'PersistedQueryNotFoundError',
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PersistedQueryNotFoundError = PersistedQueryNotFoundError;
|
||||
class PersistedQueryNotSupportedError extends ApolloError {
|
||||
constructor() {
|
||||
super('PersistedQueryNotSupported', 'PERSISTED_QUERY_NOT_SUPPORTED');
|
||||
Object.defineProperty(this, 'name', {
|
||||
value: 'PersistedQueryNotSupportedError',
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PersistedQueryNotSupportedError = PersistedQueryNotSupportedError;
|
||||
class UserInputError extends ApolloError {
|
||||
constructor(message, properties) {
|
||||
super(message, 'BAD_USER_INPUT', properties);
|
||||
Object.defineProperty(this, 'name', { value: 'UserInputError' });
|
||||
}
|
||||
}
|
||||
exports.UserInputError = UserInputError;
|
||||
function formatApolloErrors(errors, options) {
|
||||
if (!options) {
|
||||
return errors.map(error => enrichError(error));
|
||||
}
|
||||
const { formatter, debug } = options;
|
||||
const enrichedErrors = errors.map(error => enrichError(error, debug));
|
||||
const makePrintable = error => {
|
||||
if (error instanceof Error) {
|
||||
const graphQLError = error;
|
||||
return Object.assign(Object.assign(Object.assign({ message: graphQLError.message }, (graphQLError.locations && { locations: graphQLError.locations })), (graphQLError.path && { path: graphQLError.path })), (graphQLError.extensions && { extensions: graphQLError.extensions }));
|
||||
}
|
||||
return error;
|
||||
};
|
||||
if (!formatter) {
|
||||
return enrichedErrors;
|
||||
}
|
||||
return enrichedErrors.map(error => {
|
||||
try {
|
||||
return makePrintable(formatter(error));
|
||||
}
|
||||
catch (err) {
|
||||
if (debug) {
|
||||
return enrichError(err, debug);
|
||||
}
|
||||
else {
|
||||
const newError = fromGraphQLError(new graphql_1.GraphQLError('Internal server error'));
|
||||
return enrichError(newError, debug);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.formatApolloErrors = formatApolloErrors;
|
||||
function hasPersistedQueryError(errors) {
|
||||
return Array.isArray(errors)
|
||||
? errors.some(error => error instanceof PersistedQueryNotFoundError ||
|
||||
error instanceof PersistedQueryNotSupportedError)
|
||||
: false;
|
||||
}
|
||||
exports.hasPersistedQueryError = hasPersistedQueryError;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/apollo-server-errors/dist/index.js.map
generated
vendored
Normal file
1
node_modules/apollo-server-errors/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
24
node_modules/apollo-server-errors/package.json
generated
vendored
Normal file
24
node_modules/apollo-server-errors/package.json
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "apollo-server-errors",
|
||||
"version": "2.5.0",
|
||||
"author": "Apollo <opensource@apollographql.com>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/apollographql/apollo-server",
|
||||
"directory": "packages/apollo-server-errors"
|
||||
},
|
||||
"homepage": "https://github.com/apollographql/apollo-server#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/apollographql/apollo-server/issues"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
|
||||
},
|
||||
"gitHead": "8a4cc583b692a30670d1893c01851259dbd70ce1"
|
||||
}
|
||||
49
node_modules/apollo-server-errors/src/__tests__/ApolloError.test.ts
generated
vendored
Normal file
49
node_modules/apollo-server-errors/src/__tests__/ApolloError.test.ts
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { ApolloError } from '..';
|
||||
|
||||
describe('ApolloError', () => {
|
||||
it("doesn't overwrite extensions when provided in the constructor", () => {
|
||||
const error = new ApolloError('My message', 'A_CODE', {
|
||||
arbitrary: 'user_data',
|
||||
});
|
||||
|
||||
expect(error.extensions).toEqual({
|
||||
code: 'A_CODE',
|
||||
arbitrary: 'user_data',
|
||||
});
|
||||
});
|
||||
|
||||
it("a code property doesn't overwrite the code provided to the constructor", () => {
|
||||
const error = new ApolloError('My message', 'A_CODE', {
|
||||
code: 'CANT_OVERWRITE',
|
||||
});
|
||||
|
||||
expect(error.extensions).toEqual({
|
||||
code: 'A_CODE',
|
||||
});
|
||||
});
|
||||
|
||||
// This is a byproduct of how we currently assign properties from the 3rd constructor
|
||||
// argument onto properties of the class itself. This is expected, but deprecated behavior
|
||||
// and as such this test should be deleted in the future when we make that breaking change.
|
||||
it("a message property doesn't overwrite the message provided to the constructor", () => {
|
||||
const error = new ApolloError('My original message', 'A_CODE', {
|
||||
message:
|
||||
"This message can't overwrite the original message, but it does end up in extensions",
|
||||
});
|
||||
|
||||
expect(error.message).toEqual('My original message');
|
||||
expect(error.extensions.message).toEqual(
|
||||
"This message can't overwrite the original message, but it does end up in extensions",
|
||||
);
|
||||
});
|
||||
|
||||
it('(back-compat) sets extensions correctly for users who use an extensions key in the third constructor argument', () => {
|
||||
const error = new ApolloError('My original message', 'A_CODE', {
|
||||
extensions: {
|
||||
arbitrary: 'user_data',
|
||||
},
|
||||
});
|
||||
|
||||
expect(error.extensions.arbitrary).toEqual('user_data');
|
||||
});
|
||||
});
|
||||
7
node_modules/apollo-server-errors/src/__tests__/tsconfig.json
generated
vendored
Normal file
7
node_modules/apollo-server-errors/src/__tests__/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.test.base",
|
||||
"include": ["**/*"],
|
||||
"references": [
|
||||
{ "path": "../../" }
|
||||
]
|
||||
}
|
||||
310
node_modules/apollo-server-errors/src/index.ts
generated
vendored
Normal file
310
node_modules/apollo-server-errors/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
import { GraphQLError, GraphQLFormattedError } from 'graphql';
|
||||
|
||||
export class ApolloError extends Error implements GraphQLError {
|
||||
public extensions: Record<string, any>;
|
||||
readonly name;
|
||||
readonly locations;
|
||||
readonly path;
|
||||
readonly source;
|
||||
readonly positions;
|
||||
readonly nodes;
|
||||
public originalError;
|
||||
|
||||
[key: string]: any;
|
||||
|
||||
constructor(
|
||||
message: string,
|
||||
code?: string,
|
||||
extensions?: Record<string, any>,
|
||||
) {
|
||||
super(message);
|
||||
|
||||
// This variable was previously named `properties`, which allowed users to set
|
||||
// arbitrary properties on the ApolloError object. This use case is still supported,
|
||||
// but deprecated in favor of using the ApolloError.extensions object instead.
|
||||
// This change intends to comply with the GraphQL spec on errors. See:
|
||||
// https://github.com/graphql/graphql-spec/blob/master/spec/Section%207%20--%20Response.md#response-format
|
||||
//
|
||||
// Going forward, users should use the ApolloError.extensions object for storing
|
||||
// and reading arbitrary data on an error, as arbitrary properties on the ApolloError
|
||||
// itself won't be supported in the future.
|
||||
//
|
||||
// XXX Filter 'message' and 'extensions' specifically so they don't overwrite the class property.
|
||||
// We _could_ filter all of the class properties, but have chosen to only do
|
||||
// so if it's an issue for other users. Please feel free to open an issue if you
|
||||
// find yourself here with this exact problem.
|
||||
if (extensions) {
|
||||
Object.keys(extensions)
|
||||
.filter(keyName => keyName !== 'message' && keyName !== 'extensions')
|
||||
.forEach(key => {
|
||||
this[key] = extensions[key];
|
||||
});
|
||||
}
|
||||
|
||||
// if no name provided, use the default. defineProperty ensures that it stays non-enumerable
|
||||
if (!this.name) {
|
||||
Object.defineProperty(this, 'name', { value: 'ApolloError' });
|
||||
}
|
||||
|
||||
// Before the mentioned change to extensions, users could previously set the extensions
|
||||
// object by providing it as a key on the third argument to the constructor.
|
||||
// This step provides backwards compatibility for those hypothetical users.
|
||||
const userProvidedExtensions = (extensions && extensions.extensions) || null;
|
||||
|
||||
this.extensions = { ...extensions, ...userProvidedExtensions, code };
|
||||
}
|
||||
}
|
||||
|
||||
function enrichError(error: Partial<GraphQLError>, debug: boolean = false) {
|
||||
// follows similar structure to https://github.com/graphql/graphql-js/blob/master/src/error/GraphQLError.js#L145-L193
|
||||
// with the addition of name
|
||||
const expanded = Object.create(Object.getPrototypeOf(error), {
|
||||
name: {
|
||||
value: error.name,
|
||||
},
|
||||
message: {
|
||||
value: error.message,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
},
|
||||
locations: {
|
||||
value: error.locations || undefined,
|
||||
enumerable: true,
|
||||
},
|
||||
path: {
|
||||
value: error.path || undefined,
|
||||
enumerable: true,
|
||||
},
|
||||
nodes: {
|
||||
value: error.nodes || undefined,
|
||||
},
|
||||
source: {
|
||||
value: error.source || undefined,
|
||||
},
|
||||
positions: {
|
||||
value: error.positions || undefined,
|
||||
},
|
||||
originalError: {
|
||||
value: error.originalError,
|
||||
},
|
||||
});
|
||||
|
||||
expanded.extensions = {
|
||||
...error.extensions,
|
||||
code:
|
||||
(error.extensions && error.extensions.code) || 'INTERNAL_SERVER_ERROR',
|
||||
exception: {
|
||||
...(error.extensions && error.extensions.exception),
|
||||
...(error.originalError as any),
|
||||
},
|
||||
};
|
||||
|
||||
// ensure that extensions is not taken from the originalError
|
||||
// graphql-js ensures that the originalError's extensions are hoisted
|
||||
// https://github.com/graphql/graphql-js/blob/0bb47b2/src/error/GraphQLError.js#L138
|
||||
delete expanded.extensions.exception.extensions;
|
||||
if (debug && !expanded.extensions.exception.stacktrace) {
|
||||
expanded.extensions.exception.stacktrace =
|
||||
(error.originalError &&
|
||||
error.originalError.stack &&
|
||||
error.originalError.stack.split('\n')) ||
|
||||
(error.stack && error.stack.split('\n'));
|
||||
}
|
||||
|
||||
if (Object.keys(expanded.extensions.exception).length === 0) {
|
||||
// remove from printing an empty object
|
||||
delete expanded.extensions.exception;
|
||||
}
|
||||
|
||||
return expanded as ApolloError;
|
||||
}
|
||||
|
||||
export function toApolloError(
|
||||
error: Error & { extensions?: Record<string, any> },
|
||||
code: string = 'INTERNAL_SERVER_ERROR',
|
||||
): Error & { extensions: Record<string, any> } {
|
||||
let err = error;
|
||||
if (err.extensions) {
|
||||
err.extensions.code = code;
|
||||
} else {
|
||||
err.extensions = { code };
|
||||
}
|
||||
return err as Error & { extensions: Record<string, any> };
|
||||
}
|
||||
|
||||
export interface ErrorOptions {
|
||||
code?: string;
|
||||
// This declaration means it takes any "class" that has a constructor that
|
||||
// takes a single string, and should be invoked via the `new` operator.
|
||||
errorClass?: new (message: string) => ApolloError;
|
||||
}
|
||||
|
||||
export function fromGraphQLError(error: GraphQLError, options?: ErrorOptions) {
|
||||
const copy: ApolloError =
|
||||
options && options.errorClass
|
||||
? new options.errorClass(error.message)
|
||||
: new ApolloError(error.message);
|
||||
|
||||
// copy enumerable keys
|
||||
Object.keys(error).forEach(key => {
|
||||
copy[key] = error[key];
|
||||
});
|
||||
|
||||
// extensions are non enumerable, so copy them directly
|
||||
copy.extensions = {
|
||||
...copy.extensions,
|
||||
...error.extensions,
|
||||
};
|
||||
|
||||
// Fallback on default for code
|
||||
if (!copy.extensions.code) {
|
||||
copy.extensions.code = (options && options.code) || 'INTERNAL_SERVER_ERROR';
|
||||
}
|
||||
|
||||
// copy the original error, while keeping all values non-enumerable, so they
|
||||
// are not printed unless directly referenced
|
||||
Object.defineProperty(copy, 'originalError', { value: {} });
|
||||
Object.getOwnPropertyNames(error).forEach(key => {
|
||||
Object.defineProperty(copy.originalError, key, { value: error[key] });
|
||||
});
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
export class SyntaxError extends ApolloError {
|
||||
constructor(message: string) {
|
||||
super(message, 'GRAPHQL_PARSE_FAILED');
|
||||
|
||||
Object.defineProperty(this, 'name', { value: 'SyntaxError' });
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidationError extends ApolloError {
|
||||
constructor(message: string) {
|
||||
super(message, 'GRAPHQL_VALIDATION_FAILED');
|
||||
|
||||
Object.defineProperty(this, 'name', { value: 'ValidationError' });
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthenticationError extends ApolloError {
|
||||
constructor(message: string) {
|
||||
super(message, 'UNAUTHENTICATED');
|
||||
|
||||
Object.defineProperty(this, 'name', { value: 'AuthenticationError' });
|
||||
}
|
||||
}
|
||||
|
||||
export class ForbiddenError extends ApolloError {
|
||||
constructor(message: string) {
|
||||
super(message, 'FORBIDDEN');
|
||||
|
||||
Object.defineProperty(this, 'name', { value: 'ForbiddenError' });
|
||||
}
|
||||
}
|
||||
|
||||
export class PersistedQueryNotFoundError extends ApolloError {
|
||||
constructor() {
|
||||
super('PersistedQueryNotFound', 'PERSISTED_QUERY_NOT_FOUND');
|
||||
|
||||
Object.defineProperty(this, 'name', {
|
||||
value: 'PersistedQueryNotFoundError',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class PersistedQueryNotSupportedError extends ApolloError {
|
||||
constructor() {
|
||||
super('PersistedQueryNotSupported', 'PERSISTED_QUERY_NOT_SUPPORTED');
|
||||
|
||||
Object.defineProperty(this, 'name', {
|
||||
value: 'PersistedQueryNotSupportedError',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class UserInputError extends ApolloError {
|
||||
constructor(message: string, properties?: Record<string, any>) {
|
||||
super(message, 'BAD_USER_INPUT', properties);
|
||||
|
||||
Object.defineProperty(this, 'name', { value: 'UserInputError' });
|
||||
}
|
||||
}
|
||||
|
||||
export function formatApolloErrors(
|
||||
errors: ReadonlyArray<Error>,
|
||||
options?: {
|
||||
formatter?: (error: GraphQLError) => GraphQLFormattedError;
|
||||
debug?: boolean;
|
||||
},
|
||||
): Array<ApolloError> {
|
||||
if (!options) {
|
||||
return errors.map(error => enrichError(error));
|
||||
}
|
||||
const { formatter, debug } = options;
|
||||
|
||||
// Errors that occur in graphql-tools can contain an errors array that contains the errors thrown in a merged schema
|
||||
// https://github.com/apollographql/graphql-tools/blob/3d53986ca/src/stitching/errors.ts#L104-L107
|
||||
//
|
||||
// They are are wrapped in an extra GraphQL error
|
||||
// https://github.com/apollographql/graphql-tools/blob/3d53986ca/src/stitching/errors.ts#L109-L113
|
||||
// which calls:
|
||||
// https://github.com/graphql/graphql-js/blob/0a30b62964/src/error/locatedError.js#L18-L37
|
||||
// Some processing for these nested errors could be done here:
|
||||
//
|
||||
// if (Array.isArray((error as any).errors)) {
|
||||
// (error as any).errors.forEach(e => flattenedErrors.push(e));
|
||||
// } else if (
|
||||
// (error as any).originalError &&
|
||||
// Array.isArray((error as any).originalError.errors)
|
||||
// ) {
|
||||
// (error as any).originalError.errors.forEach(e => flattenedErrors.push(e));
|
||||
// } else {
|
||||
// flattenedErrors.push(error);
|
||||
// }
|
||||
|
||||
const enrichedErrors = errors.map(error => enrichError(error, debug));
|
||||
const makePrintable = error => {
|
||||
if (error instanceof Error) {
|
||||
// Error defines its `message` and other fields as non-enumerable, meaning JSON.stringigfy does not print them.
|
||||
const graphQLError = error as GraphQLFormattedError;
|
||||
return {
|
||||
message: graphQLError.message,
|
||||
...(graphQLError.locations && { locations: graphQLError.locations }),
|
||||
...(graphQLError.path && { path: graphQLError.path }),
|
||||
...(graphQLError.extensions && { extensions: graphQLError.extensions }),
|
||||
};
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
if (!formatter) {
|
||||
return enrichedErrors;
|
||||
}
|
||||
|
||||
return enrichedErrors.map(error => {
|
||||
try {
|
||||
return makePrintable(formatter(error));
|
||||
} catch (err) {
|
||||
if (debug) {
|
||||
return enrichError(err, debug);
|
||||
} else {
|
||||
// obscure error
|
||||
const newError = fromGraphQLError(
|
||||
new GraphQLError('Internal server error'),
|
||||
);
|
||||
return enrichError(newError, debug);
|
||||
}
|
||||
}
|
||||
}) as Array<ApolloError>;
|
||||
}
|
||||
|
||||
export function hasPersistedQueryError(errors: Array<Error>): boolean {
|
||||
return Array.isArray(errors)
|
||||
? errors.some(
|
||||
error =>
|
||||
error instanceof PersistedQueryNotFoundError ||
|
||||
error instanceof PersistedQueryNotSupportedError,
|
||||
)
|
||||
: false;
|
||||
}
|
||||
Reference in New Issue
Block a user