Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

fix: set customErrorInfo on zisi/esbuild errors #700

Merged
merged 8 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/runtimes/node/bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { basename, dirname, extname, resolve, join } = require('path')
const esbuild = require('@netlify/esbuild')
const { tmpName } = require('tmp-promise')

const { RUNTIME_JS } = require('../../utils/consts')
const { JS_BUNDLER_ESBUILD, RUNTIME_JS } = require('../../utils/consts')
const { getPathWithExtension, safeUnlink } = require('../../utils/fs')

const { getBundlerTarget } = require('./bundler_target')
Expand Down Expand Up @@ -106,7 +106,10 @@ const bundleJsFile = async function ({
warnings,
}
} catch (error) {
error.customErrorInfo = { type: 'functionsBundling', location: { functionName: name, runtime: RUNTIME_JS } }
error.customErrorInfo = {
type: 'functionsBundling',
location: { bundler: JS_BUNDLER_ESBUILD, functionName: name, runtime: RUNTIME_JS },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to show the bundler and/or the runtime in the error message title?

https://github.com/netlify/build/blob/a6ab7b9dbfebd21bcedcb5dbada4d1620cd6192a/packages/build/src/error/type.js#L86

Please note we do show the location fields in the error details, which is printed in the build logs. Also, the location fields are always sent to Bugsnag. Just wondering what you think about the error message title itself (which is shown in the error header and in the deploy summary).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally don't think we need to show the runtime in the message because it probably offers less clarity than the noise it introduces. I think that field is useful mostly for Bugsnag.

However, on that link I do see that we show functionName, which means that the field is mandatory. We don't have the function name when using esbuild from the ZISI flow. Adding it will mean passing that parameter around in a lot of functions, which I'm not super excited about, but it'll have to be done.

I'll add to this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 94c3248. Some of these functions are called recursively, and without types it's a bit difficult to ensure all cases are covered, but I think I've done it!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your help! 🙌🏻

}

throw error
}
Expand Down
8 changes: 8 additions & 0 deletions src/runtimes/node/list_imports.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const esbuild = require('@netlify/esbuild')
const isBuiltinModule = require('is-builtin-module')
const { tmpName } = require('tmp-promise')

const { JS_BUNDLER_ZISI, RUNTIME_JS } = require('../../utils/consts')
const { safeUnlink } = require('../../utils/fs')

// Maximum number of log messages that an esbuild instance will produce. This
Expand Down Expand Up @@ -49,6 +50,13 @@ const listImports = async ({ path }) => {
plugins: [getListImportsPlugin({ imports, path })],
target: 'esnext',
})
} catch (error) {
error.customErrorInfo = {
type: 'functionsBundling',
location: { bundler: JS_BUNDLER_ZISI, path, runtime: RUNTIME_JS },
}

throw error
} finally {
await safeUnlink(targetPath)
}
Expand Down
5 changes: 5 additions & 0 deletions tests/fixtures/node-syntax-error/function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const immutable = 1

immutable = 3

module.exports = { immutable }
27 changes: 23 additions & 4 deletions tests/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1609,18 +1609,37 @@ test('Throws an error if the `archiveFormat` property contains an invalid value`
)
})

test('Adds `type: "functionsBundling"` to esbuild bundling errors', async (t) => {
test('Adds `type: "functionsBundling"` to user errors (esbuild)', async (t) => {
try {
await zipNode(t, 'node-module-missing', {
await zipNode(t, 'node-syntax-error', {
opts: { config: { '*': { nodeBundler: ESBUILD } } },
})

t.fail('Function did not throw')
t.fail('Bundling should have thrown')
} catch (error) {
t.deepEqual(error.customErrorInfo, {
type: 'functionsBundling',
location: { functionName: 'function', runtime: 'js' },
location: { bundler: ESBUILD, functionName: 'function', runtime: 'js' },
})
}
})

// TO DO: Once https://github.com/netlify/zip-it-and-ship-it/pull/699 lands,
// merge this with the test above and make `parseWithEsbuild` part of a new
// variation.
test('Adds `type: "functionsBundling"` to user errors (ZISI)', async (t) => {
try {
await zipNode(t, 'node-syntax-error', {
opts: { config: { '*': { nodeBundler: JS_BUNDLER_ZISI } }, featureFlags: { parseWithEsbuild: true } },
})

t.fail('Bundling should have thrown')
} catch (error) {
const { customErrorInfo } = error

t.is(customErrorInfo.type, 'functionsBundling')
t.is(customErrorInfo.location.bundler, JS_BUNDLER_ZISI)
t.is(customErrorInfo.location.runtime, 'js')
}
})

Expand Down