diff --git a/src/__tests__/http-test.ts b/src/__tests__/http-test.ts index ffca7714..5098caee 100644 --- a/src/__tests__/http-test.ts +++ b/src/__tests__/http-test.ts @@ -248,6 +248,35 @@ function runTests(server: Server) { }); }); + it('Reports validation errors for dynamic schema', async () => { + const app = server(); + + app.get( + urlString(), + graphqlHTTP(() => Promise.resolve({ schema: TestSchema })), + ); + + const response = await app.request().get( + urlString({ + query: '{ test, unknownOne, unknownTwo }', + }), + ); + + expect(response.status).to.equal(400); + expect(JSON.parse(response.text)).to.deep.equal({ + errors: [ + { + message: 'Cannot query field "unknownOne" on type "QueryRoot".', + locations: [{ line: 1, column: 9 }], + }, + { + message: 'Cannot query field "unknownTwo" on type "QueryRoot".', + locations: [{ line: 1, column: 21 }], + }, + ], + }); + }); + it('Errors when missing operation name', async () => { const app = server(); diff --git a/src/__tests__/usage-test.ts b/src/__tests__/usage-test.ts index d63ee572..866a8672 100644 --- a/src/__tests__/usage-test.ts +++ b/src/__tests__/usage-test.ts @@ -117,4 +117,19 @@ describe('Useful errors when incorrectly used', () => { ], }); }); + + it('requires a valid schema if static schema is defined in options', () => { + const options = () => ({ + // @ts-expect-error + schema: new GraphQLSchema({ directives: [null] }), + }); + const { schema } = options(); + expect(() => { + graphqlHTTP({ schema }); + }).to.throw('GraphQL schema validation failed'); + + expect(() => { + graphqlHTTP(options); + }).not.to.throw(); + }); }); diff --git a/src/index.ts b/src/index.ts index 23b4d930..9814fce1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -190,6 +190,12 @@ export function graphqlHTTP(options: Options): Middleware { throw new Error('GraphQL middleware requires options.'); } + const staticSchemaValidationErrors = + 'schema' in options ? validateSchema(options.schema) : undefined; + + if (staticSchemaValidationErrors?.length) { + throw Error('GraphQL schema validation failed'); + } return async function graphqlMiddleware( request: Request, response: Response, @@ -272,7 +278,8 @@ export function graphqlHTTP(options: Options): Middleware { } // Validate Schema - const schemaValidationErrors = validateSchema(schema); + const schemaValidationErrors = + staticSchemaValidationErrors ?? validateSchema(schema); if (schemaValidationErrors.length > 0) { // Return 500: Internal Server Error if invalid schema. throw httpError(500, 'GraphQL schema validation error.', {