Skip to content

Commit c0d2eba

Browse files
authored
feat(gatsby-source-contentful): improve gatsby-plugin-image errors (#35068)
* feat(gatsby-source-contentful): improve gatsby-plugin-image errors * add tests and move to onPreInit
1 parent 2b8f279 commit c0d2eba

File tree

4 files changed

+136
-5
lines changed

4 files changed

+136
-5
lines changed

packages/gatsby-source-contentful/src/__tests__/gatsby-node.js

+93-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// @ts-check
22
// This is more an integration test than it is a unit test. We try to mock as little as we can
33
import _ from "lodash"
4-
import { createSchemaCustomization, sourceNodes } from "../gatsby-node"
4+
import {
5+
createSchemaCustomization,
6+
sourceNodes,
7+
onPreInit,
8+
} from "../gatsby-node"
59
import { fetchContent, fetchContentTypes } from "../fetch"
610
import { makeId } from "../normalize"
711

@@ -328,6 +332,94 @@ describe(`gatsby-node`, () => {
328332
reporter.panic.mockClear()
329333
})
330334

335+
let hasImported = false
336+
describe(`onPreInit`, () => {
337+
it(`should pass when gatsby-plugin-image is installed and configured`, async () => {
338+
const reporter = {
339+
panic: jest.fn(err => {
340+
throw err
341+
}),
342+
}
343+
344+
await onPreInit({
345+
store: {
346+
getState: () => {
347+
return {
348+
flattenedPlugins: [
349+
{
350+
name: `gatsby-plugin-image`,
351+
},
352+
],
353+
}
354+
},
355+
},
356+
reporter,
357+
})
358+
})
359+
360+
it(`should throw when gatsby-plugin-image is not installed`, async () => {
361+
const reporter = {
362+
panic: jest.fn(err => {
363+
throw err
364+
}),
365+
}
366+
367+
jest.doMock(`gatsby-plugin-image/graphql-utils`, () => {
368+
if (hasImported) {
369+
return jest.requireActual(`gatsby-plugin-image/graphql-utils`)
370+
}
371+
372+
// only throw once
373+
hasImported = true
374+
throw new Error(`not installed`)
375+
})
376+
377+
expect.assertions(2)
378+
try {
379+
await onPreInit({ store: {}, reporter })
380+
} catch (err) {
381+
console.log(err)
382+
expect(err.id).toBe(`111005`)
383+
expect(err.context).toMatchInlineSnapshot(`
384+
Object {
385+
"sourceMessage": "gatsby-plugin-image is missing from your project.
386+
Please install \\"gatsby-plugin-image\\".",
387+
}
388+
`)
389+
}
390+
})
391+
it(`should throw when gatsby-plugin-image is not configured`, async () => {
392+
const reporter = {
393+
panic: jest.fn(err => {
394+
throw err
395+
}),
396+
}
397+
398+
expect.assertions(2)
399+
try {
400+
await onPreInit({
401+
store: {
402+
getState: () => {
403+
return {
404+
flattenedPlugins: [],
405+
}
406+
},
407+
},
408+
reporter,
409+
})
410+
} catch (err) {
411+
console.log(err)
412+
expect(err.id).toBe(`111005`)
413+
expect(err.context).toMatchInlineSnapshot(`
414+
Object {
415+
"sourceMessage": "gatsby-plugin-image is missing from your gatsby-config file.
416+
Please add \\"gatsby-plugin-image\\" to your plugins array.",
417+
}
418+
`)
419+
}
420+
})
421+
})
422+
331423
it(`should create nodes from initial payload`, async () => {
332424
// @ts-ignore
333425
fetchContent.mockImplementationOnce(startersBlogFixture.initialSync)

packages/gatsby-source-contentful/src/create-schema-customization.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ export async function createSchemaCustomization(
7474
pluginConfig,
7575
})
7676
}
77+
const { getGatsbyImageFieldConfig } = await import(
78+
`gatsby-plugin-image/graphql-utils`
79+
)
7780

7881
const contentfulTypes = [
7982
schema.buildInterfaceType({
@@ -96,10 +99,6 @@ export async function createSchemaCustomization(
9699
}),
97100
]
98101

99-
const { getGatsbyImageFieldConfig } = await import(
100-
`gatsby-plugin-image/graphql-utils`
101-
)
102-
103102
contentfulTypes.push(
104103
addRemoteFilePolyfillInterface(
105104
schema.buildObjectType({

packages/gatsby-source-contentful/src/gatsby-node.js

+29
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import origFetch from "node-fetch"
44
import fetchRetry from "@vercel/fetch-retry"
55
import { polyfillImageServiceDevRoutes } from "gatsby-plugin-utils/polyfill-remote-file"
66
export { setFieldsOnGraphQLNodeType } from "./extend-node-type"
7+
import { CODES } from "./report"
78

89
import { maskText } from "./plugin-options"
910

@@ -42,6 +43,34 @@ const validateContentfulAccess = async pluginOptions => {
4243
return undefined
4344
}
4445

46+
export const onPreInit = async ({ store, reporter }) => {
47+
// if gatsby-plugin-image is not installed
48+
try {
49+
await import(`gatsby-plugin-image/graphql-utils`)
50+
} catch (err) {
51+
reporter.panic({
52+
id: CODES.GatsbyPluginMissing,
53+
context: {
54+
sourceMessage: `gatsby-plugin-image is missing from your project.\nPlease install "gatsby-plugin-image".`,
55+
},
56+
})
57+
}
58+
59+
// if gatsby-plugin-image is not configured
60+
if (
61+
!store
62+
.getState()
63+
.flattenedPlugins.find(plugin => plugin.name === `gatsby-plugin-image`)
64+
) {
65+
reporter.panic({
66+
id: CODES.GatsbyPluginMissing,
67+
context: {
68+
sourceMessage: `gatsby-plugin-image is missing from your gatsby-config file.\nPlease add "gatsby-plugin-image" to your plugins array.`,
69+
},
70+
})
71+
}
72+
}
73+
4574
export const pluginOptionsSchema = ({ Joi }) =>
4675
Joi.object()
4776
.keys({

packages/gatsby-source-contentful/src/report.js

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const CODES = {
66
SelfSignedCertificate: `111002`,
77
SyncError: `111003`,
88
FetchContentTypes: `111004`,
9+
GatsbyPluginMissing: `111005`,
910
}
1011

1112
export const ERROR_MAP = {
@@ -34,4 +35,14 @@ export const ERROR_MAP = {
3435
level: `ERROR`,
3536
category: `THIRD_PARTY`,
3637
},
38+
[CODES.FetchTags]: {
39+
text: context => context.sourceMessage,
40+
level: `ERROR`,
41+
category: `THIRD_PARTY`,
42+
},
43+
[CODES.GatsbyPluginMissing]: {
44+
text: context => context.sourceMessage,
45+
level: `ERROR`,
46+
category: `USER`,
47+
},
3748
}

0 commit comments

Comments
 (0)