From bfbaae1d8d7c4a098c28cf8204f504d3304b79df Mon Sep 17 00:00:00 2001 From: Bryce Franzen Date: Wed, 13 Apr 2022 15:03:34 -0700 Subject: [PATCH] Update to have types and use/export them --- .../src/ApolloServerErrors.ts | 42 ++++++----- packages/apollo-server-errors/src/index.ts | 2 + packages/apollo-server-errors/src/types.ts | 73 +++++++++++++++++++ 3 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 packages/apollo-server-errors/src/index.ts create mode 100644 packages/apollo-server-errors/src/types.ts diff --git a/packages/apollo-server-errors/src/ApolloServerErrors.ts b/packages/apollo-server-errors/src/ApolloServerErrors.ts index 61b7ed2bf18..7c4cbbb0b4f 100644 --- a/packages/apollo-server-errors/src/ApolloServerErrors.ts +++ b/packages/apollo-server-errors/src/ApolloServerErrors.ts @@ -7,6 +7,7 @@ import { printError, formatError, } from 'graphql'; +import { ErrorCode, ErrorName } from './types'; declare module 'graphql' { export interface GraphQLErrorExtensions { @@ -40,7 +41,7 @@ export class ApolloError extends Error implements GraphQLError { // if no name provided, use the default. defineProperty ensures that it stays non-enumerable if (!this.name) { - Object.defineProperty(this, 'name', { value: 'ApolloError' }); + Object.defineProperty(this, 'name', { value: ErrorName.APOLLO_ERROR }); } if (extensions?.extensions) { @@ -115,7 +116,7 @@ function enrichError(error: Partial, debug: boolean = false) { expanded.extensions = { ...error.extensions, - code: error.extensions?.code || 'INTERNAL_SERVER_ERROR', + code: error.extensions?.code || ErrorCode.INTERNAL_SERVER_ERROR, exception: { ...error.extensions?.exception, ...(error.originalError as any), @@ -141,7 +142,7 @@ function enrichError(error: Partial, debug: boolean = false) { export function toApolloError( error: Error & { extensions?: Record }, - code: string = 'INTERNAL_SERVER_ERROR', + code: string = ErrorCode.INTERNAL_SERVER_ERROR, ): Error & { extensions: Record } { let err = error; if (err.extensions) { @@ -180,7 +181,7 @@ export function fromGraphQLError(error: GraphQLError, options?: ErrorOptions) { // Fallback on default for code if (!copy.extensions.code) { - copy.extensions.code = options?.code || 'INTERNAL_SERVER_ERROR'; + copy.extensions.code = options?.code || ErrorCode.INTERNAL_SERVER_ERROR; } // copy the original error, while keeping all values non-enumerable, so they @@ -197,61 +198,66 @@ export function fromGraphQLError(error: GraphQLError, options?: ErrorOptions) { export class SyntaxError extends ApolloError { constructor(message: string) { - super(message, 'GRAPHQL_PARSE_FAILED'); + super(message, ErrorCode.GRAPHQL_PARSE_FAILED); - Object.defineProperty(this, 'name', { value: 'SyntaxError' }); + Object.defineProperty(this, 'name', { value: ErrorName.SYNTAX_ERROR }); } } export class ValidationError extends ApolloError { constructor(message: string) { - super(message, 'GRAPHQL_VALIDATION_FAILED'); + super(message, ErrorCode.GRAPHQL_VALIDATION_FAILED); - Object.defineProperty(this, 'name', { value: 'ValidationError' }); + Object.defineProperty(this, 'name', { value: ErrorName.VALIDATION_ERROR }); } } export class AuthenticationError extends ApolloError { constructor(message: string, extensions?: Record) { - super(message, 'UNAUTHENTICATED', extensions); + super(message, ErrorCode.UNAUTHENTICATED, extensions); - Object.defineProperty(this, 'name', { value: 'AuthenticationError' }); + Object.defineProperty(this, 'name', { + value: ErrorName.AUTHENTICATION_ERROR, + }); } } export class ForbiddenError extends ApolloError { constructor(message: string, extensions?: Record) { - super(message, 'FORBIDDEN', extensions); + super(message, ErrorCode.FORBIDDEN, extensions); - Object.defineProperty(this, 'name', { value: 'ForbiddenError' }); + Object.defineProperty(this, 'name', { value: ErrorName.FORBIDDEN_ERROR }); } } export class PersistedQueryNotFoundError extends ApolloError { constructor() { - super('PersistedQueryNotFound', 'PERSISTED_QUERY_NOT_FOUND'); + super('PersistedQueryNotFound', ErrorCode.PERSISTED_QUERY_NOT_FOUND); Object.defineProperty(this, 'name', { - value: 'PersistedQueryNotFoundError', + value: ErrorName.PERSISTED_QUERY_NOT_FOUND_ERROR, }); } } export class PersistedQueryNotSupportedError extends ApolloError { constructor() { - super('PersistedQueryNotSupported', 'PERSISTED_QUERY_NOT_SUPPORTED'); + super( + 'PersistedQueryNotSupported', + ErrorCode.PERSISTED_QUERY_NOT_SUPPORTED, + ); Object.defineProperty(this, 'name', { - value: 'PersistedQueryNotSupportedError', + value: ErrorName.PERSISTED_QUERY_NOT_SUPPORTED_ERROR, }); } } export class UserInputError extends ApolloError { constructor(message: string, extensions?: Record) { - super(message, 'BAD_USER_INPUT', extensions); + super(message, ErrorCode.BAD_USER_INPUT, extensions); - Object.defineProperty(this, 'name', { value: 'UserInputError' }); + Object.defineProperty(this, 'name', { value: ErrorName.USER_INPUT_ERROR }); } } diff --git a/packages/apollo-server-errors/src/index.ts b/packages/apollo-server-errors/src/index.ts new file mode 100644 index 00000000000..89872b95fca --- /dev/null +++ b/packages/apollo-server-errors/src/index.ts @@ -0,0 +1,2 @@ +export * from './ApolloServerErrors'; +export * from './types'; diff --git a/packages/apollo-server-errors/src/types.ts b/packages/apollo-server-errors/src/types.ts new file mode 100644 index 00000000000..573a627ec78 --- /dev/null +++ b/packages/apollo-server-errors/src/types.ts @@ -0,0 +1,73 @@ +export enum ErrorCode { + /** + * The GraphQL operation string contains a syntax error. + */ + GRAPHQL_PARSE_FAILED = 'GRAPHQL_PARSE_FAILED', + /** + * The GraphQL operation is not valid against the server's schema. + */ + GRAPHQL_VALIDATION_FAILED = 'GRAPHQL_VALIDATION_FAILED', + /** + * The GraphQL operation includes an invalid value for a field argument. + */ + BAD_USER_INPUT = 'BAD_USER_INPUT', + /** + * The server failed to authenticate with a required data source, such as a REST API. + */ + UNAUTHENTICATED = 'UNAUTHENTICATED', + /** + * The server was unauthorized to access a required data source, such as a REST API. + */ + FORBIDDEN = 'FORBIDDEN', + /** + * A client sent the hash of a query string to execute via automatic persisted queries, but the query was not in the APQ cache. + */ + PERSISTED_QUERY_NOT_FOUND = 'PERSISTED_QUERY_NOT_FOUND', + /** + * A client sent the hash of a query string to execute via automatic persisted queries, but the server has disabled APQ. + */ + PERSISTED_QUERY_NOT_SUPPORTED = 'PERSISTED_QUERY_NOT_SUPPORTED', + /** + * This is the default error code returned by any ApolloError instance that doesn't specify a different code. + */ + INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR', +} + +export type TErrorCode = `${ErrorCode}`; + +export enum ErrorName { + /** + * A error occurred without a name provided. This is the default name. + */ + APOLLO_ERROR = 'ApolloError', + /** + * The GraphQL operation string contains a syntax error. + */ + SYNTAX_ERROR = 'SyntaxError', + /** + * The GraphQL operation is not valid against the server's schema. + */ + VALIDATION_ERROR = 'ValidationError', + /** + * The server failed to authenticate with a required data source, such as a REST API. + */ + AUTHENTICATION_ERROR = 'AuthenticationError', + /** + * The server was unauthorized to access a required data source, such as a REST API. + */ + FORBIDDEN_ERROR = 'ForbiddenError', + /** + * A client sent the hash of a query string to execute via automatic persisted queries, but the query was not in the APQ cache. + */ + PERSISTED_QUERY_NOT_FOUND_ERROR = 'PersistedQueryNotFoundError', + /** + * A client sent the hash of a query string to execute via automatic persisted queries, but the server has disabled APQ. + */ + PERSISTED_QUERY_NOT_SUPPORTED_ERROR = 'PersistedQueryNotSupportedError', + /** + * The GraphQL operation includes an invalid value for a field argument. + */ + USER_INPUT_ERROR = 'UserInputError', +} + +export type TErrorName = `${ErrorName}`;