From 269a4412948e2f5aa753d2dfd3e381c2775e4405 Mon Sep 17 00:00:00 2001 From: Khuda Dad Nomani Date: Fri, 20 Oct 2023 13:10:05 +0100 Subject: [PATCH] feat: add better error message. --- src/lib/functions.ts | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/lib/functions.ts b/src/lib/functions.ts index f046d3abb..1dd61ad11 100644 --- a/src/lib/functions.ts +++ b/src/lib/functions.ts @@ -14,6 +14,8 @@ import { import { pathToFileURL } from 'url' import GleeError from '../errors/glee-error.js' import { getParsedAsyncAPI } from './asyncapiFile.js' +import Debug from 'debug' +const debug = Debug('glee:functions') interface FunctionInfo { run: GleeFunction @@ -53,30 +55,40 @@ const { GLEE_DIR, GLEE_FUNCTIONS_DIR } = getConfigs() export const functions: Map = new Map() export async function register(dir: string) { + debug(`Attempting to register functions from directory: ${dir}`) try { const statsDir = await stat(dir) - if (!statsDir.isDirectory()) return + if (!statsDir.isDirectory()){ + debug('Provided path is not a directory. Skipping.') + return + } } catch (e) { - if (e.code === 'ENOENT') return + debug(`Error while checking directory: ${e}`) throw e } try { const files = await walkdir.async(dir, { return_object: true }) + debug(`Found function files: ${Object.keys(files)}`) + return await Promise.all( Object.keys(files).map(async (filePath) => { try { const functionName = basename(filePath, extname(filePath)) + debug(`Registering function: ${functionName}`) + const { default: fn } = await import(pathToFileURL(filePath).href) functions.set(functionName, { run: fn, }) } catch (e) { + debug(`Error while registering function:`) console.error(e) } }) ) } catch (e) { + debug(`Error while walking directory:`) console.error(e) } } @@ -91,18 +103,26 @@ export async function trigger({ message: GleeMessage }) { try { + debug(`Triggering function for operation ID: ${operationId}`) const parsedAsyncAPI = await getParsedAsyncAPI() - let res = await functions - .get(operationId) - .run(gleeMessageToFunctionEvent(message, app)) - if (res === undefined) res = null + const operationFunction = functions.get(operationId) + if(!operationFunction){ + const errMsg = `Failed to trigger function: No function registered for operation ID "${operationId}". please make sure you have a function named: "${operationId}(.js|.ts)" in your functions directory.` + logError(new Error(errMsg ), { + highlightedWords: [`"${operationId}"`], + }) + return + } + let functionResult = await operationFunction.run(gleeMessageToFunctionEvent(message, app)) + if (functionResult === undefined) functionResult = null const { humanReadableError, errors, isValid } = validateData( - res, + functionResult, FunctionReturnSchema ) if (!isValid) { + debug(`Function ${operationId} returned invalid data.`) const err = new GleeError({ humanReadableError, errors, @@ -116,7 +136,7 @@ export async function trigger({ return } - res?.send?.forEach((msg) => { + functionResult?.send?.forEach((msg) => { const localServerProtocols = ['ws', 'wss', 'http', 'https'] const serverProtocol = parsedAsyncAPI.servers().get(msg.server || message.serverName).protocol().toLocaleLowerCase() const isBroadcast = @@ -134,7 +154,7 @@ export async function trigger({ ) }) - res?.reply?.forEach((msg) => { + functionResult?.reply?.forEach((msg) => { message.reply({ payload: msg.payload, headers: msg.headers,