I'm having issues with CallbackFunction and AWS la...
# typescript
l
I'm having issues with CallbackFunction and AWS lambdas, at least when called form Jest (unit test context).
The stack track I'm seeing:
Copy code
<ref *1> TypeError: pf.parseFunction is not a function or its return value is not iterable
    at /pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/runtime/closure/createClosure.ts:418:44
    at Generator.next (<anonymous>)
    at /pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/pulumi/runtime/closure/createClosure.js:21:71
    at new Promise (<anonymous>)
    at Object.<anonymous>.__awaiter (/pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/pulumi/runtime/closure/createClosure.js:17:12)
    at serializeWorkerAsync (/pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/pulumi/runtime/closure/createClosure.js:210:20)
    at /pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/runtime/closure/createClosure.ts:377:26
    at Generator.next (<anonymous>)
    at fulfilled (/pulumi/projects/pulumi-infrastructure/node_modules/@pulumi/pulumi/runtime/closure/createClosure.js:18:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  promise: Promise { <rejected> [Circular *1] }
It's happening during the call to
new CallbackFunction
. Never saw it before, and I've created plenty of CallbackFunctions.
I've replaced my callback with
callback: async () => {}
and I'm still getting that exception.
g
I would think this is going to be hard to debug without the code for the test and the lambda function you are running?
l
I've cut everything right down to essentially no code. I'm creating a ComponentResource that contains a CallbackFunction with `callback: async () => {}`; I'm creating that ComponentResource in my unit test `beforeEach()`; and my only test is
expect(true).toBe(true)
. But I'm getting that exception. So it looks like the mixin code itself is not 100% compatible with the unit test harness in TS/JS.
Interestingly, I can't see the trace when I run through the test tool in VSCode; I have to run from the command line. It's apparently a leak of some kind, and it's happening in a thread that isn't affecting the test.
Interestingly, my first attempt failed because I didn't provide a role: it looked like it wasn't using the test harness (the
setUpState()
function). That might be a lead....
When I create the role myself, which definitely is hooked into the harness. it gets past that problem...
Maybe some other resource is being created, using a default provider, or some other provider that isn't the one I want?
Doesn't look like it. But AssetArchive is in use, which might not work nicely with test context. serializeFunction in generate is a bit iffy, when testing... and since I don't want to actually create a lambda, it should be safe to not call this code when we're running tests...
g
I have built several lambdas and tried to use CallbackFunction but in the end, it broke a lot of my code because it could not find the TS/JS files during the serialization. I had problems, especially with external packages e.g
zod
So we abandoned CallbackFunction entirely and added
yarn build
step before deployment and then attach the code as an archive
code: new pulumi.asset.AssetArchive
this way you can run the code as usual, all imports work and everything
l
Hmm.. the CallbackFunction works for me when running Pulumi, it just produces a pile of errors when running in a test. I'd quite like to extract the runs-in-the-cloud code from the infra code though, it seems wrong that it's in the same file: it confuses people some of the time. Do you have an example of how to set your solution up? I've never built lambda archive outside of Pulumi code before.
g
It is pretty much the same as building any static website create a
yarn workspace
then
yarn workspace @org/lambda build
then use standard function
this.fn = new aws.lambda.Function(
with
Copy code
code: new pulumi.asset.AssetArchive({
          dist: new pulumi.asset.FileArchive(path.join(lambdaDir, args.serviceDef.dirName, "dist")),
          node_modules: new pulumi.asset.FileArchive(path.join(lambdaDir, args.serviceDef.dirName, "node_modules")),
          // If you have a shared library you need to manually pick up the shared lib package because AssetArchive does not follow
          // the symlinks generated by the yarn workspace
          "node_modules/@org/lambda-lib": new pulumi.asset.FileArchive(path.join(lambdaDir, "lib")),
        })