export async function runLambdaFunction()

in src/shared/sam/localLambdaRunner.ts [335:428]


export async function runLambdaFunction(
    ctx: ExtContext,
    config: SamLaunchRequestArgs,
    onAfterBuild: () => Promise<void>
): Promise<SamLaunchRequestArgs> {
    // Verify if Docker is running
    const dockerResponse = await new ChildProcess('docker', ['ps'], { logging: 'no' }).run()
    if (dockerResponse.exitCode !== 0 || dockerResponse.stdout.includes('error during connect')) {
        throw new Error('Running AWS SAM projects locally requires Docker. Is it installed and running?')
    }
    // Switch over to the output channel so the user has feedback that we're getting things ready
    ctx.outputChannel.show(true)
    if (!config.noDebug) {
        const msg =
            (config.invokeTarget.target === 'api' ? `API "${config.api?.path}", ` : '') +
            `Lambda "${config.handlerName}"`
        getLogger('channel').info(localize('AWS.output.sam.local.startDebug', 'Preparing to debug locally: {0}', msg))
    } else {
        getLogger('channel').info(
            localize('AWS.output.sam.local.startRun', 'Preparing to run locally: {0}', config.handlerName)
        )
    }

    const envVars = {
        ...(config.awsCredentials ? asEnvironmentVariables(config.awsCredentials) : {}),
        ...(config.aws?.region ? { AWS_DEFAULT_REGION: config.aws.region } : {}),
    }

    const timer = createLambdaTimer(ctx.settings)

    if (!(await buildLambdaHandler(timer, envVars, config))) {
        return config
    }

    await onAfterBuild()
    timer.refresh()

    if (!(await invokeLambdaHandler(timer, envVars, config))) {
        return config
    }

    if (!config.noDebug) {
        if (config.invokeTarget.target === 'api') {
            const payload =
                config.eventPayloadFile === undefined
                    ? undefined
                    : JSON.parse(await readFile(config.eventPayloadFile, { encoding: 'utf-8' }))
            // Send the request to the local API server.
            await requestLocalApi(ctx, config.api!, config.apiPort!, payload)
            // Wait for cue messages ("Starting debugger" etc.) before attach.
            if (!(await samStartApi)) {
                return config
            }
        }

        if (config.onWillAttachDebugger) {
            getLogger('channel').info(
                localize('AWS.output.sam.local.waiting', 'Waiting for SAM application to start...')
            )
            await config.onWillAttachDebugger(config.debugPort!, timer)
        }
        // HACK: remove non-serializable properties before attaching.
        // TODO: revisit this :)
        // eslint-disable-next-line @typescript-eslint/unbound-method
        config.onWillAttachDebugger = undefined
        config.samLocalInvokeCommand = undefined

        await attachDebugger({
            debugConfig: config,
            retryDelayMillis: ATTACH_DEBUGGER_RETRY_DELAY_MILLIS,
            onRecordAttachDebuggerMetric: (attachResult: boolean | undefined, attempts: number): void => {
                telemetry.recordSamAttachDebugger({
                    lambdaPackageType: isImageLambdaConfig(config) ? 'Image' : 'Zip',
                    runtime: config.runtime as telemetry.Runtime,
                    result: attachResult ? 'Succeeded' : 'Failed',
                    attempts: attempts,
                    duration: timer.elapsedTime,
                    architecture: config.architecture,
                })
            },
        })
            .then(r => {
                if (r.success) {
                    showDebugConsole()
                }
            })
            .catch(e => {
                getLogger().error(`Failed to debug: ${e}`)
                globals.outputChannel.appendLine(`Failed to debug: ${e}`)
            })
    }

    return config
}