Skip to content

Commit

Permalink
feat(gatsby): Improve structured errors around GraphQL (#20120)
Browse files Browse the repository at this point in the history
* move generic graphql error to structured error

* 85920: Variables in StaticQueries

* 85921: Wrong variable type in query

* 85922: Wrong subfield usage

* 85923: Error about missing field - can be caused by many things

* 85924: Explicitly defined a type and the value on a field is wrong

* 85925: non-nullable field

* 11321: graphql is not defined

* beginning of gatsby-node errors

* some linting

* 85910: improve messsage

* remove console logs

* fix typo

* also use optionalGraphQLInfo for 11321 error

* update jest snapshots

* fix some more tests and update snapshots

* don't color code frame in tests

* actually apply tests "fix" to both codeframe in the error

Co-authored-by: GatsbyJS Bot <mathews.kyle+gatsbybot@gmail.com>
Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
  • Loading branch information
3 people committed Dec 20, 2019
1 parent fa2824d commit a5740f9
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 97 deletions.
97 changes: 94 additions & 3 deletions packages/gatsby-cli/src/structured-errors/error-map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const { stripIndent, stripIndents } = require(`common-tags`)

const optionalGraphQLInfo = context =>
`${context.codeFrame ? `\n\n${context.codeFrame}` : ``}${
context.filePath ? `\n\nFile path: ${context.filePath}` : ``
}${context.urlPath ? `\nUrl path: ${context.urlPath}` : ``}${
context.plugin ? `\nPlugin: ${context.plugin}` : ``
}`

const errorMap = {
"": {
text: context => {
Expand Down Expand Up @@ -31,10 +38,14 @@ const errorMap = {
},
"85901": {
text: context =>
`There was an error in your GraphQL query:\n\n${context.sourceMessage}`,
stripIndent(`
There was an error in your GraphQL query:\n\n${
context.sourceMessage
}${optionalGraphQLInfo(context)}`),
type: `GRAPHQL`,
level: `ERROR`,
},
// Deprecated
"85907": {
text: context =>
`There was an error in your GraphQL query:\n\n${context.message}`,
Expand All @@ -52,6 +63,7 @@ const errorMap = {
type: `GRAPHQL`,
level: `ERROR`,
},
// Deprecated
"85909": {
text: context => context.sourceMessage,
type: `GRAPHQL`,
Expand All @@ -60,17 +72,23 @@ const errorMap = {
"85910": {
text: context =>
stripIndents(`
Multiple "root" queries found in file: "${context.name}" and "${context.otherName}".
Multiple "root" queries found: "${context.name}" and "${context.otherName}".
Only the first ("${context.otherName}") will be registered.
Instead of:
${context.beforeCodeFrame}
Do:
${context.afterCodeFrame}
This can happen when you use two page/static queries in one file. Please combine those into one query.
If you're defining multiple components (each with a static query) in one file, you'll need to move each component to its own file.
`),
type: `GRAPHQL`,
level: `ERROR`,
docsUrl: `https://www.gatsbyjs.org/docs/graphql/`,
},
"85911": {
text: context =>
Expand Down Expand Up @@ -146,6 +164,70 @@ const errorMap = {
type: `GRAPHQL`,
level: `ERROR`,
},
// Undefined variables in Queries
"85920": {
text: context => {
const generalMessage = stripIndents(`You might have a typo in the variable name "${context.variableName}" or you didn't provide the variable via context to this page query. Have a look at the docs to learn how to add data to context:
https://www.gatsbyjs.org/docs/page-query/#how-to-add-query-variables-to-a-page-query`)

const staticQueryMessage = stripIndents(`If you're not using a page query but a StaticQuery / useStaticQuery you see this error because they currently don't support variables. To learn more about the limitations of StaticQuery / useStaticQuery, please visit these docs:
https://www.gatsbyjs.org/docs/static-query/
https://www.gatsbyjs.org/docs/use-static-query/`)

return stripIndent(`
There was an error in your GraphQL query:\n\n${
context.sourceMessage
}${optionalGraphQLInfo(
context
)}\n\n${generalMessage}\n\n${staticQueryMessage}`)
},
type: `GRAPHQL`,
level: `ERROR`,
},
"85921": {
text: context =>
`There was an error in your GraphQL query:\n\n${context.sourceMessage}\n\nIf you're e.g. filtering for specific nodes make sure that you choose the correct field (that has the same type "${context.inputType}") or adjust the context variable to the type "${context.expectedType}".`,
type: `GRAPHQL`,
level: `ERROR`,
},
"85922": {
text: context =>
`There was an error in your GraphQL query:\n\n${context.sourceMessage}\n\nThis can happen if you e.g. accidentally added { } to the field "${context.fieldName}". If you didn't expect "${context.fieldName}" to be of type "${context.fieldType}" make sure that your input source and/or plugin is correct.`,
type: `GRAPHQL`,
level: `ERROR`,
},
"85923": {
text: context =>
`There was an error in your GraphQL query:\n\n${context.sourceMessage}\n\nIf you don't expect "${context.field}" to exist on the type "${context.type}" it is most likely a typo.\nHowever, if you expect "${context.field}" to exist there are a couple of solutions to common problems:\n\n- If you added a new data source and/or changed something inside gatsby-node.js/gatsby-config.js, please try a restart of your development server\n- The field might be accessible in another subfield, please try your query in GraphiQL and use the GraphiQL explorer to see which fields you can query and what shape they have\n- You want to optionally use your field "${context.field}" and right now it is not used anywhere. Therefore Gatsby can't infer the type and add it to the GraphQL schema. A quick fix is to add a least one entry with that field ("dummy content")\n\nIt is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned "dummy content". Visit our docs to learn how you can define the schema for "${context.type}":\nhttps://www.gatsbyjs.org/docs/schema-customization/#creating-type-definitions`,
type: `GRAPHQL`,
level: `ERROR`,
},
"85924": {
text: context =>
`There was an error in your GraphQL query:\n\n${
context.sourceMessage
}\n\nThis can happen when you or a plugin/theme explicitly defined the GraphQL schema for this GraphQL object type via the schema customization API and "${
context.value
}" doesn't match the (scalar) type of "${
context.type
}".${optionalGraphQLInfo(context)}`,
type: `GRAPHQL`,
level: `ERROR`,
},
"85925": {
text: context =>
`There was an error in your GraphQL query:\n\n${
context.sourceMessage
}\n\nThe field "${
context.field
}" was explicitly defined as non-nullable via the schema customization API (by yourself or a plugin/theme). This means that this field is not optional and you have to define a value. If this is not your desired behavior and you defined the schema yourself, go to "createTypes" in gatsby-node.js. If you're using a plugin/theme, you can learn more here on how to fix field types:\nhttps://www.gatsbyjs.org/docs/schema-customization/#fixing-field-types${optionalGraphQLInfo(
context
)}`,
type: `GRAPHQL`,
level: `ERROR`,
},
// Config errors
"10123": {
text: context =>
Expand Down Expand Up @@ -193,7 +275,9 @@ const errorMap = {
// Plugin errors
"11321": {
text: context =>
`"${context.pluginName}" threw an error while running the ${context.api} lifecycle:\n\n${context.message}`,
`"${context.pluginName}" threw an error while running the ${
context.api
} lifecycle:\n\n${context.message}${optionalGraphQLInfo(context)}`,
type: `PLUGIN`,
level: `ERROR`,
},
Expand Down Expand Up @@ -286,6 +370,13 @@ const errorMap = {
.join(`\n`),
level: `ERROR`,
},
// "X" is not defined in Gatsby's node APIs
"11330": {
text: context =>
`"${context.pluginName}" threw an error while running the ${context.api} lifecycle:\n\n${context.message}\n\n${context.codeFrame}\n\nMake sure that you don't have a typo somewhere and use valid arguments in ${context.api} lifecycle.\nLearn more about ${context.api} here: https://www.gatsbyjs.org/docs/node-apis/#${context.api}`,
type: `PLUGIN`,
level: `ERROR`,
},
// node object didn't pass validation
"11467": {
text: context =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`totally vague one 1`] = `
exports[`specific one 1`] = `
Object {
"context": Object {
"sourceMessage": "foo bar",
"sourceMessage": "Variable \\"Foo\\" of required type \\"Bar\\" was not provided.",
"variableName": "Foo",
"variableType": "Bar",
},
"filePath": "test.js",
"id": "85901",
"id": "85920",
"location": Object {
"start": Object {
"column": 10,
Expand All @@ -16,13 +18,13 @@ Object {
}
`;

exports[`vague one 1`] = `
exports[`totally vague one 1`] = `
Object {
"context": Object {
"message": "- Unknown field 'fdnjkgd' on type 'SiteSiteMetadata'.",
"sourceMessage": "foo bar",
},
"filePath": "test.js",
"id": "85907",
"id": "85901",
"location": Object {
"start": Object {
"column": 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,38 @@ Object {
}
`;
exports[`actual compiling errors on double root 1`] = `
Array [
Object {
"context": Object {
"afterCodeFrame": " 1 | query anotherQueryAndMockFileQuery {
2 | allPostsJson {
3 | #...
4 | }
5 | allPostsJson {
6 | #...
7 | }
8 | }",
"beforeCodeFrame": " 1 | query mockFileQuery {
2 | allPostsJson {
3 | #...
4 | }
5 | }
6 |
7 | query AnotherQuery {
8 | allPostsJson {
9 | #...
10 | }
11 | }",
"name": "AnotherQuery",
"otherName": "mockFileQuery",
},
"filePath": "mockFile",
"id": "85910",
},
]
`;
exports[`actual compiling errors on double root 2`] = `
Map {
"mockFile" => Object {
Expand Down
7 changes: 3 additions & 4 deletions packages/gatsby/src/query/__tests__/error-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import errorParser from "../error-parser"

it.each([
[
`vague one`,
`Encountered 1 error(s):
- Unknown field 'fdnjkgd' on type 'SiteSiteMetadata'.`,
`85907`,
`specific one`,
`Variable "Foo" of required type "Bar" was not provided.`,
`85920`,
],
[`totally vague one`, `foo bar`, `85901`],
])(`%s`, (_name, message, expectedId) => {
Expand Down
48 changes: 5 additions & 43 deletions packages/gatsby/src/query/__tests__/query-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -676,41 +676,7 @@ describe(`actual compiling`, () => {
errors.push(e)
},
})
expect(errors).toMatchInlineSnapshot(
`
Array [
Object {
"context": Object {
"afterCodeFrame": " 1 | query anotherQueryAndMockFileQuery {
2 | bar {
3 | #...
4 | }
5 | foo {
6 | #...
7 | }
8 | }",
"beforeCodeFrame": " 1 | query mockFileQuery {
2 | bar {
3 | #...
4 | }
5 | }
6 |` +
` ` +
`
7 | query AnotherQuery {
8 | foo {
9 | #...
10 | }
11 | }",
"name": "AnotherQuery",
"otherName": "mockFileQuery",
},
"filePath": "mockFile",
"id": "85910",
},
]
`
)
expect(errors).toMatchSnapshot()
expect(result).toMatchSnapshot()
})

Expand Down Expand Up @@ -786,16 +752,12 @@ describe(`actual compiling`, () => {
Array [
Object {
"context": Object {
"sourceMessage": "Cannot query field \\"id\\" on type \\"PostsJsonConnection\\".
GraphQL request:3:16
2 | allPostsJson {
3 | id
| ^
4 | }",
"field": "id",
"sourceMessage": "Cannot query field \\"id\\" on type \\"PostsJsonConnection\\".",
"type": "PostsJsonConnection",
},
"filePath": "mockFile",
"id": "85901",
"id": "85923",
"location": Object {
"end": Object {
"column": 16,
Expand Down

0 comments on commit a5740f9

Please sign in to comment.