error executing bot: 'process is not defined' when...
# support
s
Hi all, I'm using the
vmContext
and the
package.json
and
esbuild-script.mjs
from the
examples/medplum-demo-bots
to build and deploy bots locally with the CLI. All works well with a simple hello world ✅ But when I include and call the AWS SDK (see below), it builds and deploys OK but I get the error
Error: process is not defined
when I run it from the CLI or medplum UI ❌ However, if I make an edit from the medplum UI and deploy and execute it, it works ✅ I don't know a whole lot about JS packaging and modules etc and I'm not fully across everything that's going on in the
esbuild-script.mjs
from the medplum example - do I need to polyfill somehow in the build script because there's no node process available? Is there a standard script/approach to this? Any help would be great Thanks!
Copy code
import { MedplumClient } from '@medplum/core';
import { OperationOutcome } from '@medplum/fhirtypes';
import { LambdaClient, InvokeCommand, InvokeCommandInput } from '@aws-sdk/client-lambda';

export async function handler(medplum: MedplumClient, event: any): Promise<OperationOutcome> {
  const lambdaClient = new LambdaClient({
    region: 'us-east-1',
    credentials: { accessKeyId: '...', secretAccessKey: '...' },
  });
  const invokeParams: InvokeCommandInput = {
    FunctionName: 'my_function',
    InvocationType: 'RequestResponse',
    Payload: JSON.stringify({
      key1: 'value1',
    }),
  };

  const lambdaResponse = await lambdaClient.send(new InvokeCommand(invokeParams));
  console.log(lambdaResponse);
  console.log('Hello World!');

  return {
    resourceType: 'OperationOutcome',
    issue: [{ severity: 'information', code: 'informational', details: { text: 'Hello World!' } }],
  } as OperationOutcome;
}
Copy code
{
  "bots": [
    {
      "name": "bot-aws-test",
      "id": "662363f7-1aae-43c0-bc1d-9b5a8640538a",
      "source": "src/bot-aws-test.ts",
      "dist": "dist/bot-aws-test.js"
    }
  ]
}
c
Hi @simonj - good catch. It looks like
process
is not included in the VMContext sandbox. You can see the exported values here: https://github.com/medplum/medplum/blob/main/packages/server/src/bots/vmcontext.ts#L50-L72 I filed a tracking ticket here: https://github.com/medplum/medplum/issues/7427 This would be an excellent first issue for an aspiring contributor, just need to add the token
process
to an array!
s
Hey @cody thanks for your help - it turned out that I needed more than just
process
to get the AWS SDK running in the sandbox, but once I added them all (below) it worked 🎉 IMHO calling AWS SDK in bots should be a supported design pattern (eg our next bot uses SQS) so if it's OK to add the additional 6 functions to the sandbox I'll open a new ticket with a more appropriate title and can submit a PR. My final question: do you have any idea why it was working if I copied/pasted the code into the Meplum bot editor UI then clicked the deploy and execute buttons 🤔 ? Is there something special that happens with the medplum bot build process that doesn't happen with the
examples/medplum-demo-bots
IDE build? It would be great to have them consistent
Copy code
const sandbox = {
  // required for AWS SDK
  process,
  setTimeout,
  clearTimeout,
  Buffer,
  setInterval,
  clearInterval,
  ...
c
> IMHO calling AWS SDK in bots should be a supported design pattern 100% agree > so if it's OK to add the additional 6 functions to the sandbox I'll open a new ticket with a more appropriate title and can submit a PR. Sounds good, go for it 👍 > do you have any idea why it was working if I copied/pasted the code into the Meplum bot editor UI then clicked the deploy and execute buttons 🤔 ? Is there something special that happens with the medplum bot build process that doesn't happen with the examples/medplum-demo-bots IDE build? It would be great to have them consistent Good question.... I agree, they should be consistent. The "build" step is unfortunately different: 1. The
medplum-demo-bots
package uses
esbuild
to compile the TypeScript to CommonJS 2. The Bot Editor UI uses the Monaco Editor / TypeScript sandbox (https://www.typescriptlang.org/dev/sandbox/) In theory, those should produce roughly the same code, but that obviously didn't happen in this case. It's possible that the TypeScript sandbox build tool added a
process
shim, or transpiled the calling code away somehow. Do you have a minimal bot example you can share? We can take a look at the CommonJS output of the 2 different lows, and see if there's a clean way to update the
esbuild
code to align them.
s
@cody gotcha! good to know. I added a minimal example and steps here: https://github.com/medplum/medplum/issues/7436 Once we've tested more with the AWS SDK I'll add a PR for the sandbox array thanks!
c
@simonj ok, found it, put up a fix: https://github.com/medplum/medplum/pull/7438 Short version: by default,
esbuild
will bundle any dependency that is not marked as
external
into the output. So, before, the entire
@aws-sdk/client-lambda
was included in the build output 😱 On the other hand, the Bot Editor / Monaco Editor / TypeScript Sandbox uses the opposite default, and assumes all dependencies are external, so does not bundle anything. The reason that works is because AWS Lambdas already include most client SDKs in the base image, so you don't need to install them or inline them, they're just already there. As a fix, I updated our build script to mark
'@aws-sdk/client-*'
as external. That's not a perfect solution (depending on which SDK and which runtime environment, you may want different behavior). But this is a better default, and anything other than this would be a pretty advanced configuration. Interesting follow-up question: Why does
process
matter here? Well, the inline code did not have access to
process
, but when the code calls
require
, that is a new context, and then it inherits it. That's a kinda wonky setup, but it works. I think adding
process
to the vmcontext sandbox is still the right call, and we should still do it. Overall, this is a great find. Thanks @simonj !
s
Sweet! Thanks for diving into the esbuild abyss, I can sleep better knowing the entire aws client isn't stowing away in our builds hehe. And glad the process mystery has been solved, that all makes sense now - we'll do some testing this week
74 Views