async handleEvent()

in src/eventHandlers/InvocationHandler.ts [40:154]


    async handleEvent(msg: rpc.IInvocationRequest): Promise<rpc.IInvocationResponse> {
        const functionId = nonNullProp(msg, 'functionId');
        let registeredFunc: RegisteredFunction | undefined;
        if (worker.app.isUsingWorkerIndexing) {
            registeredFunc = worker.app.functions[functionId];
        } else {
            registeredFunc = getLegacyFunction(functionId);
        }

        if (!registeredFunc) {
            throw new AzFuncSystemError(`Function code for '${functionId}' is not loaded and cannot be invoked.`);
        }

        let { metadata, callback } = registeredFunc;

        const msgCategory = `${nonNullProp(metadata, 'name')}.Invocation`;
        const coreCtx = new CoreInvocationContext(
            toCoreInvocationRequest(msg),
            toCoreFunctionMetadata(metadata),
            msgCategory
        );

        // Log invocation details to ensure the invocation received by node worker
        coreCtx.log(
            'debug',
            'system',
            `Worker ${worker.id} received FunctionInvocationRequest with invocationId ${msg.invocationId}`
        );

        const programmingModel: ProgrammingModel = nonNullProp(worker.app, 'programmingModel');
        const invocModel = await programmingModel.getInvocationModel(coreCtx);

        const hookData: HookData = {};
        let { context, inputs } = await invocModel.getArguments();
        coreCtx.logContext = { hookData, invocationContext: context };

        const preInvocContext: PreInvocationContext = {
            get hookData() {
                return hookData;
            },
            set hookData(_obj) {
                throw new ReadOnlyError('hookData');
            },
            get appHookData() {
                return worker.app.appHookData;
            },
            set appHookData(_obj) {
                throw new ReadOnlyError('appHookData');
            },
            get invocationContext() {
                return context;
            },
            set invocationContext(_obj) {
                throw new ReadOnlyError('invocationContext');
            },
            functionCallback: callback,
            inputs,
        };

        coreCtx.state = 'preInvocationHooks';
        try {
            await executeHooks('preInvocation', preInvocContext, msg.invocationId, msgCategory);
        } finally {
            coreCtx.state = undefined;
        }

        inputs = preInvocContext.inputs;
        callback = preInvocContext.functionCallback;

        const postInvocContext: PostInvocationContext = {
            get hookData() {
                return hookData;
            },
            set hookData(_obj) {
                throw new ReadOnlyError('hookData');
            },
            get appHookData() {
                return worker.app.appHookData;
            },
            set appHookData(_obj) {
                throw new ReadOnlyError('appHookData');
            },
            get invocationContext() {
                return context;
            },
            set invocationContext(_obj) {
                throw new ReadOnlyError('invocationContext');
            },
            inputs,
            result: null,
            error: null,
        };

        coreCtx.state = 'invocation';
        try {
            postInvocContext.result = await invocModel.invokeFunction(context, inputs, callback);
        } catch (err) {
            postInvocContext.error = err;
        } finally {
            coreCtx.state = undefined;
        }

        coreCtx.state = 'postInvocationHooks';
        try {
            await executeHooks('postInvocation', postInvocContext, msg.invocationId, msgCategory);
        } finally {
            coreCtx.state = undefined;
        }

        if (isError(postInvocContext.error)) {
            throw postInvocContext.error;
        }

        return fromCoreInvocationResponse(await invocModel.getResponse(context, postInvocContext.result));
    }