Skip to content

Commit b5d1ad9

Browse files
authored
Report plugin load errors as statuses (#1286)
1 parent 30fbba8 commit b5d1ad9

File tree

15 files changed

+337
-28
lines changed

15 files changed

+337
-28
lines changed

packages/build/src/core/main.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const build = async function(flags) {
6363
} = await loadConfig(flagsA)
6464

6565
try {
66-
const pluginsOptions = await getPluginsOptions({ netlifyConfig, buildDir, constants, mode })
66+
const pluginsOptions = await getPluginsOptions({ netlifyConfig, buildDir, constants, mode, api })
6767
await installLocalPluginsDependencies({ pluginsOptions, buildDir, mode })
6868

6969
const { commandsCount, error, statuses } = await buildRun({
@@ -79,6 +79,7 @@ const build = async function(flags) {
7979
context,
8080
branch,
8181
mode,
82+
api,
8283
errorMonitor,
8384
})
8485

@@ -122,6 +123,7 @@ const buildRun = async function({
122123
context,
123124
branch,
124125
mode,
126+
api,
125127
errorMonitor,
126128
}) {
127129
const utilsData = await startUtils(buildDir)
@@ -141,6 +143,8 @@ const buildRun = async function({
141143
token,
142144
dry,
143145
constants,
146+
mode,
147+
api,
144148
errorMonitor,
145149
})
146150
} finally {
@@ -160,6 +164,8 @@ const executeCommands = async function({
160164
token,
161165
dry,
162166
constants,
167+
mode,
168+
api,
163169
errorMonitor,
164170
}) {
165171
const pluginsCommands = await loadPlugins({
@@ -169,6 +175,8 @@ const executeCommands = async function({
169175
utilsData,
170176
token,
171177
constants,
178+
mode,
179+
api,
172180
})
173181

174182
const { commands, commandsCount } = getCommands(pluginsCommands, netlifyConfig)

packages/build/src/core/status.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { env } = require('process')
22

3+
const { serializeErrorStatus } = require('../error/parse/serialize_status')
34
const { logStatuses } = require('../log/main')
45

56
// The last event handler of a plugin (except for `onError` and `onEnd`)
@@ -57,6 +58,13 @@ const canOverrideStatus = function(formerStatus, newStatus) {
5758
return formerStatus.state === 'success' || newStatus.state !== 'success'
5859
}
5960

61+
// Errors that happen during plugin loads should be reported as error statuses
62+
const reportPluginLoadError = async function({ error, api, mode, event, package, version }) {
63+
const errorStatus = serializeErrorStatus(error)
64+
const statuses = [{ ...errorStatus, event, package, version }]
65+
await reportStatuses(statuses, api, mode)
66+
}
67+
6068
const reportStatuses = async function(statuses, api, mode) {
6169
printStatuses(statuses, mode)
6270
await sendStatuses(statuses, api, mode)
@@ -98,4 +106,4 @@ const sendStatus = async function(api, { package, version, state, event, title,
98106
})
99107
}
100108

101-
module.exports = { getSuccessStatus, addStatus, reportStatuses }
109+
module.exports = { getSuccessStatus, addStatus, reportPluginLoadError, reportStatuses }

packages/build/src/plugins/load.js

+37-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
const { reportPluginLoadError } = require('../core/status')
2+
13
const { callChild } = require('./ipc')
24

35
// Retrieve all plugins commands
46
// Can use either a module name or a file path to the plugin.
5-
const loadPlugins = async function({ pluginsOptions, childProcesses, netlifyConfig, utilsData, token, constants }) {
7+
const loadPlugins = async function({
8+
pluginsOptions,
9+
childProcesses,
10+
netlifyConfig,
11+
utilsData,
12+
token,
13+
constants,
14+
mode,
15+
api,
16+
}) {
617
const pluginsCommands = await Promise.all(
718
pluginsOptions.map((pluginOptions, index) =>
819
loadPlugin(pluginOptions, {
@@ -12,6 +23,8 @@ const loadPlugins = async function({ pluginsOptions, childProcesses, netlifyConf
1223
utilsData,
1324
token,
1425
constants,
26+
mode,
27+
api,
1528
}),
1629
),
1730
)
@@ -22,26 +35,32 @@ const loadPlugins = async function({ pluginsOptions, childProcesses, netlifyConf
2235
// Retrieve plugin commands for one plugin.
2336
// Do it by executing the plugin `load` event handler.
2437
const loadPlugin = async function(
25-
{ package, packageJson, pluginPath, manifest, inputs, local, core },
26-
{ childProcesses, index, netlifyConfig, utilsData, token, constants },
38+
{ package, packageJson, packageJson: { version } = {}, pluginPath, manifest, inputs, local, core },
39+
{ childProcesses, index, netlifyConfig, utilsData, token, constants, mode, api },
2740
) {
2841
const { childProcess } = childProcesses[index]
42+
const event = 'load'
2943

30-
const { pluginCommands } = await callChild(
31-
childProcess,
32-
'load',
33-
{ pluginPath, manifest, inputs, netlifyConfig, utilsData, token, constants },
34-
{ plugin: { package, packageJson }, location: { event: 'load', package, local } },
35-
)
36-
const pluginCommandsA = pluginCommands.map(({ event }) => ({
37-
event,
38-
package,
39-
local,
40-
core,
41-
packageJson,
42-
childProcess,
43-
}))
44-
return pluginCommandsA
44+
try {
45+
const { pluginCommands } = await callChild(
46+
childProcess,
47+
'load',
48+
{ pluginPath, manifest, inputs, netlifyConfig, utilsData, token, constants },
49+
{ plugin: { package, packageJson }, location: { event, package, local } },
50+
)
51+
const pluginCommandsA = pluginCommands.map(({ event }) => ({
52+
event,
53+
package,
54+
local,
55+
core,
56+
packageJson,
57+
childProcess,
58+
}))
59+
return pluginCommandsA
60+
} catch (error) {
61+
await reportPluginLoadError({ error, api, mode, event, package, version })
62+
throw error
63+
}
4564
}
4665

4766
module.exports = { loadPlugins }
+14-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1+
const { reportPluginLoadError } = require('../../core/status')
2+
13
const { checkInputs } = require('./check')
24
const { loadManifest } = require('./load')
35
const { getManifestPath } = require('./path')
46

57
// Load plugin's `manifest.yml`
6-
const useManifest = async function({ package, local, inputs }, { pluginDir, packageDir, packageJson }) {
8+
const useManifest = async function(
9+
{ package, local, inputs },
10+
{ pluginDir, packageDir, packageJson, packageJson: { version }, mode, api },
11+
) {
712
const manifestPath = await getManifestPath(pluginDir, packageDir)
813

914
if (manifestPath === undefined) {
1015
return { manifest: {}, inputs }
1116
}
1217

13-
const manifest = await loadManifest({ manifestPath, package, packageJson, local })
14-
const inputsA = checkInputs({ inputs, manifest, package, packageJson, local })
15-
return { manifest, inputs: inputsA }
18+
try {
19+
const manifest = await loadManifest({ manifestPath, package, packageJson, local })
20+
const inputsA = checkInputs({ inputs, manifest, package, packageJson, local })
21+
return { manifest, inputs: inputsA }
22+
} catch (error) {
23+
await reportPluginLoadError({ error, api, mode, event: 'load', package, version })
24+
throw error
25+
}
1626
}
1727

1828
module.exports = { useManifest }

packages/build/src/plugins/options.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ const { getPackageJson } = require('./package')
1111

1212
// Load plugin options (specified by user in `config.plugins`)
1313
// Do not allow user override of core plugins
14-
const getPluginsOptions = async function({ netlifyConfig: { plugins }, buildDir, constants: { FUNCTIONS_SRC }, mode }) {
14+
const getPluginsOptions = async function({
15+
netlifyConfig: { plugins },
16+
buildDir,
17+
constants: { FUNCTIONS_SRC },
18+
mode,
19+
api,
20+
}) {
1521
const corePlugins = getCorePlugins(FUNCTIONS_SRC)
1622
const allCorePlugins = corePlugins.filter(corePlugin => !isOptionalCore(corePlugin, plugins))
1723
const userPlugins = plugins.filter(({ package }) => !CORE_PLUGINS.includes(package))
1824
const pluginsOptions = [...allCorePlugins, ...userPlugins].map(normalizePluginOptions)
1925
await installMissingPlugins({ pluginsOptions, buildDir, mode })
2026
await checkDeprecatedFunctionsInstall(plugins, FUNCTIONS_SRC, buildDir)
2127
const pluginsOptionsA = await Promise.all(
22-
pluginsOptions.map(pluginOptions => loadPluginFiles({ pluginOptions, buildDir })),
28+
pluginsOptions.map(pluginOptions => loadPluginFiles({ pluginOptions, buildDir, mode, api })),
2329
)
2430
return pluginsOptionsA
2531
}
@@ -36,11 +42,17 @@ const normalizePluginOptions = function({ package, location = package, core = fa
3642

3743
// Retrieve plugin's main file path.
3844
// Then load plugin's `package.json` and `manifest.yml`.
39-
const loadPluginFiles = async function({ pluginOptions, pluginOptions: { location }, buildDir }) {
45+
const loadPluginFiles = async function({ pluginOptions, pluginOptions: { location }, buildDir, mode, api }) {
4046
const pluginPath = await resolveLocation(location, buildDir)
4147
const pluginDir = dirname(pluginPath)
4248
const { packageDir, packageJson } = await getPackageJson({ pluginDir })
43-
const { manifest, inputs: inputsA } = await useManifest(pluginOptions, { pluginDir, packageDir, packageJson })
49+
const { manifest, inputs: inputsA } = await useManifest(pluginOptions, {
50+
pluginDir,
51+
packageDir,
52+
packageJson,
53+
mode,
54+
api,
55+
})
4456
return { ...pluginOptions, pluginPath, packageDir, packageJson, manifest, inputs: inputsA }
4557
}
4658

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name: plugin
2+
inputs: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[[plugins]]
2+
package = "./plugin.js"
3+
4+
[plugins.inputs]
5+
test = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[[plugins]]
2+
package = "./plugin.js"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const throwError = function() {
2+
throw new Error('test')
3+
}
4+
5+
throwError()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[[plugins]]
2+
package = "./plugin.js"
3+
4+
[plugins.inputs]
5+
test = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = false

0 commit comments

Comments
 (0)