From 6d3a67b7a9cbbceeaeba2d5e3c21cb406a8bc47a Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Tue, 22 Aug 2023 03:42:47 -0700 Subject: [PATCH] fix: log actual errors instead of just strings with console.error so that Cloud Logging can detect error severity level correctly --- src/loader.ts | 22 ++++++++++++---------- src/main.ts | 9 ++------- test/loader.ts | 12 ++++-------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/loader.ts b/src/loader.ts index b1a2d6cc..9ff20348 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -26,6 +26,13 @@ import {HandlerFunction} from './functions'; import {SignatureType} from './types'; import {getRegisteredFunction} from './function_registry'; +export class LoaderError extends Error { + constructor(message) { + super('Could not load the function: ' + message) + this.name = 'LoaderError' + } +} + // Dynamic import function required to load user code packaged as an // ES module is only available on Node.js v13.2.0 and up. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility @@ -93,23 +100,21 @@ export async function getUserFunction( try { const functionModulePath = getFunctionModulePath(codeLocation); if (functionModulePath === null) { - console.error( + throw new LoaderError( `Provided code location '${codeLocation}' is not a loadable module.` + '\nDid you specify the correct location for the module defining ' + 'your function?' ); - return null; } let functionModule; const esModule = await isEsModule(functionModulePath); if (esModule) { if (semver.lt(process.version, MIN_NODE_VERSION_ESMODULES)) { - console.error( + throw new LoaderError( `Cannot load ES Module on Node.js ${process.version}. ` + `Please upgrade to Node.js v${MIN_NODE_VERSION_ESMODULES} and up.` ); - return null; } // Resolve module path to file:// URL. Required for windows support. const fpath = pathToFileURL(functionModulePath); @@ -136,19 +141,17 @@ export async function getUserFunction( }, functionModule); if (typeof userFunction === 'undefined') { - console.error( + throw new LoaderError( `Function '${functionTarget}' is not defined in the provided ` + 'module.\nDid you specify the correct target function to execute?' ); - return null; } if (typeof userFunction !== 'function') { - console.error( + throw new LoaderError( `'${functionTarget}' needs to be of type function. Got: ` + `${typeof userFunction}` ); - return null; } return {userFunction: userFunction as HandlerFunction, signatureType}; @@ -163,11 +166,10 @@ export async function getUserFunction( } else { additionalHint = 'Is there a syntax error in your code?\n'; } - console.error( + throw new LoaderError( `Provided module can't be loaded.\n${additionalHint}` + `Detailed stack trace: ${err.stack}` ); - return null; } } diff --git a/src/main.ts b/src/main.ts index 4aaaba1c..06013f88 100644 --- a/src/main.ts +++ b/src/main.ts @@ -38,11 +38,6 @@ export const main = async () => { options.target, options.signatureType ); - if (!loadedFunction) { - console.error('Could not load the function, shutting down.'); - // eslint-disable-next-line no-process-exit - process.exit(1); - } const {userFunction, signatureType} = loadedFunction; const server = getServer(userFunction!, signatureType); const errorHandler = new ErrorHandler(server); @@ -58,8 +53,8 @@ export const main = async () => { }) .setTimeout(0); // Disable automatic timeout on incoming connections. } catch (e) { - if (e instanceof OptionsError) { - console.error(e.message); + if (e instanceof OptionsError || e instanceof LoaderError) { + console.error(e); // eslint-disable-next-line no-process-exit process.exit(1); } diff --git a/test/loader.ts b/test/loader.ts index 1fd2968b..e5dc2716 100644 --- a/test/loader.ts +++ b/test/loader.ts @@ -94,23 +94,19 @@ describe('loading function', () => { } it('fails to load a module that does not exist', async () => { - const loadedFunction = await loader.getUserFunction( + expect(await loader.getUserFunction( process.cwd() + '/test/data/does_not_exist', 'functionDoesNotExist', 'http' - ); - - assert.strictEqual(loadedFunction, null); + )).toThrowErrorOfType(LoaderError); }); it('fails to load a function that does not exist', async () => { - const loadedFunction = await loader.getUserFunction( + expect(await loader.getUserFunction( process.cwd() + '/test/data/with_main', 'functionDoesNotExist', 'http' - ); - - assert.strictEqual(loadedFunction, null); + )).toThrowErrorOfType(LoaderError); }); it('loads a declaratively registered function', async () => {