Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: gracefully fail Edge Functions in case of deno binary issues #4685

Merged
merged 20 commits into from
Jun 23, 2022
Merged
Changes from 11 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
578aad6
fix: gracefully fail in case deno binary issue
jackiewmacharia Jun 9, 2022
b5ed9ce
fix: fix linting
jackiewmacharia Jun 9, 2022
06b3f64
fix: fix typo
jackiewmacharia Jun 9, 2022
3fcb21c
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 9, 2022
48c8101
fix: update error text
jackiewmacharia Jun 9, 2022
aae01e0
fix: move error message to edge-bundler
jackiewmacharia Jun 14, 2022
5066fba
fix: log error
jackiewmacharia Jun 14, 2022
86254fe
chore: update contributors field
jackiewmacharia Jun 14, 2022
de3c686
fix: get spinner stae from error object
jackiewmacharia Jun 15, 2022
2de6cba
Merge branch 'fix/gracefully-fail-in-case-deno-binary-issue' of githu…
jackiewmacharia Jun 15, 2022
9b399e3
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 15, 2022
b6dee4a
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 15, 2022
6c2f344
chore: move error handling to initializeProxy and use custom error lo…
jackiewmacharia Jun 15, 2022
1f146ae
fix: reduce functionality covered by try/catch
jackiewmacharia Jun 16, 2022
9474027
fix: clean up catch block
jackiewmacharia Jun 17, 2022
257cd54
fix: fix linting
jackiewmacharia Jun 17, 2022
b41906a
chore: optional error value for onAfterDownload
jackiewmacharia Jun 17, 2022
72be888
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 17, 2022
064dd07
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 22, 2022
df7f247
Merge branch 'main' into fix/gracefully-fail-in-case-deno-binary-issue
jackiewmacharia Jun 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 48 additions & 33 deletions src/lib/edge-functions/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { cwd, env } = require('process')
const getAvailablePort = require('get-port')
const { v4: generateUUID } = require('uuid')

const { NETLIFYDEVERR, NETLIFYDEVWARN, chalk, log } = require('../../utils/command-helpers')
const { BANG, NETLIFYDEVERR, NETLIFYDEVWARN, chalk, log } = require('../../utils/command-helpers')
const { getGeoLocation } = require('../geo-location')
const { getPathInProject } = require('../settings')
const { startSpinner, stopSpinner } = require('../spinner')
Expand All @@ -22,8 +22,11 @@ const LOCAL_HOST = '127.0.0.1'
const getDownloadUpdateFunctions = () => {
let spinner

const onAfterDownload = () => {
stopSpinner({ spinner })
/**
* @param {Error | null} error
*/
const onAfterDownload = (error) => {
stopSpinner({ error: Boolean(error), spinner })
}

const onBeforeDownload = () => {
Expand Down Expand Up @@ -80,18 +83,22 @@ const initializeProxy = async ({
return
}

const [geoLocation, { registry }] = await Promise.all([
const [geoLocation, preppedServer] = await Promise.all([
getGeoLocation({ mode: geolocationMode, offline, state }),
server,
])

if (preppedServer instanceof Error) {
return
}

// Setting header with geolocation.
req.headers[headers.Geo] = JSON.stringify(geoLocation)

await registry.initialize()
await preppedServer.registry.initialize()

const url = new URL(req.url, `http://${LOCAL_HOST}:${mainPort}`)
const { functionNames, orphanedDeclarations } = await registry.matchURLPath(url.pathname)
const { functionNames, orphanedDeclarations } = await preppedServer.registry.matchURLPath(url.pathname)

// If the request matches a config declaration for an Edge Function without
// a matching function file, we warn the user.
Expand Down Expand Up @@ -141,34 +148,42 @@ const prepareServer = async ({
port,
projectDir,
}) => {
const bundler = await import('@netlify/edge-bundler')
const distImportMapPath = getPathInProject([DIST_IMPORT_MAP_PATH])
const runIsolate = await bundler.serve({
...getDownloadUpdateFunctions(),
certificatePath,
debug: env.NETLIFY_DENO_DEBUG === 'true',
distImportMapPath,
formatExportTypeError: (name) =>
`${NETLIFYDEVERR} ${chalk.red('Failed')} to load Edge Function ${chalk.yellow(
name,
)}. The file does not seem to have a function as the default export.`,
formatImportError: (name) => `${NETLIFYDEVERR} ${chalk.red('Failed')} to run Edge Function ${chalk.yellow(name)}:`,
importMaps,
inspectSettings,
port,
})
const registry = new EdgeFunctionsRegistry({
bundler,
config,
configPath,
directories,
getUpdatedConfig,
internalFunctions,
projectDir,
runIsolate,
})
try {
const bundler = await import('@netlify/edge-bundler')
const distImportMapPath = getPathInProject([DIST_IMPORT_MAP_PATH])
const runIsolate = await bundler.serve({
...getDownloadUpdateFunctions(),
certificatePath,
debug: env.NETLIFY_DENO_DEBUG === 'true',
distImportMapPath,
formatExportTypeError: (name) =>
`${NETLIFYDEVERR} ${chalk.red('Failed')} to load Edge Function ${chalk.yellow(
name,
)}. The file does not seem to have a function as the default export.`,
formatImportError: (name) =>
`${NETLIFYDEVERR} ${chalk.red('Failed')} to run Edge Function ${chalk.yellow(name)}:`,
importMaps,
inspectSettings,
port,
})
const registry = new EdgeFunctionsRegistry({
bundler,
config,
configPath,
directories,
getUpdatedConfig,
internalFunctions,
projectDir,
runIsolate,
})

return { registry, runIsolate }
return { registry, runIsolate }
} catch (error) {
log(`${chalk.red(BANG)} ${error.message}`)
jackiewmacharia marked this conversation as resolved.
Show resolved Hide resolved
// return the error so we can listen for the error instance and break execution in initializeProxy()
// using this instead of throw allows us to continue using netlify dev command if we run into a deno binary error
return error
}
}

module.exports = { handleProxyRequest, initializeProxy, isEdgeFunctionsRequest }