Skip to main content

Error Codes

API Gateway does not supported computed property names

Error Code: Functionless(10010) Error Type: ERROR

Computed Property Names are not supported in API Gateway.

For example:

new AwsMethod(
($input) => $AWS.DynamoDB.GetItem({
Table: table,
// invalid, all property names must be literals
[computedProperty]: prop
})
);

To workaround, be sure to only use literal property names.


API Gateway does not support spread assignment expressions

Error Code: Functionless(10011) Error Type: ERROR

Due to limitations in API Gateway's VTL engine (no $util.toJson, for example) it is not possible to fully support spread expressions.

For example:

new AwsMethod(
() => {},
($input) => ({
hello: "world",
...$input.data
})
);

To workaround the limitation, explicitly specify each property.

new AwsMethod(
() => {},
($input) => ({
hello: "world",
propA: $input.data.propA,
propB: $input.data.propB,
})
);

API gateway response mapping template cannot call integration

Error Code: Functionless(10013) Error Type: ERROR

Code running within an API Gateway's response mapping template must not attempt to call any integration. It can only perform data transformation.

new AwsMethod(
...,
() => {
// INVALID! - you cannot call an integration from within a response mapping template
return $AWS.DynamoDB.GetItem({
Table: table,
...
});
}
)

To workaround, make sure to only call an integration from within the request mapping function.


ApiGateway Unsupported Reference

Error Code: Functionless(10029) Error Type: ERROR

ApiGateway supports the use of many integrations like Function and StepFunction.

Other references to data outside of of the AwsMethod are not supported.

const myObject = new Object();
const func = new Function(this, 'func', async () => { ... });
new AwsMethod(..., async () => {
// invalid
myObject;
// invalid
$util.autoUlid();
// valid
return func();
}, ...);

AppSync Unsupported Reference

Error Code: Functionless(10028) Error Type: ERROR

AppSync supports the use of many integrations like Function and StepFunction. It also supports special utility functions through $util.

Other references to data outside of of the AppsyncResolver or AppsyncField are not supported.

const myObject = new Object();
const func = new Function(this, 'func', async () => { ... });
new AppsyncResolver(..., async () => {
// invalid
myObject;
// valid
$util.autoUlid();
// valid
return func();
});

Appsync Integration invocations must be unidirectional and defined statically

Error Code: Functionless(10020) Error Type: ERROR

Appsync Integration invocations must be unidirectional and defined statically.

As stated in the AppSync Pipeline Resolvers Documents:

Pipeline resolver execution flow is unidirectional and defined statically on the resolver.

const func = new Function(stack, 'id', async () => {});

new AppsyncResolver(..., async ($context) => {
// valid
const f = await func();
// valid
await func();
if($context.arguments.value) {
// invalid - not statically defined
await func();
}
while($context.arguments.value) {
// invalid
await func();
}
// valid
return func();
});

Workaround:

One workaround would be to invoke a Function (or ExpressStepFunction) which handles the conditional parts of the workflow.

The result of this example would be to call the conditionalFunc statically and call func conditionally.

const func = new Function(stack, 'id', async () => {});

const conditionalFunc = new Function(stack, 'id', async (value) => {
if(value) {
return func();
}
return null;
})

new AppsyncResolver(..., async ($context) => {
const conditionalResult = await conditionalFunc();
return conditionalResult;
});

Argument must be an inline Function

Error Code: Functionless(10002) Error Type: ERROR

The argument must be an inline Function.

const func = () => {
// ..
}
// invalid - `func` must be an inline Function
new Function(this, id, func);

To fix, inline the func implementation.

// option 1 - arrow function
new Function(this, id, async () => { .. });

// option 2 - function
new Function(this, id, async function () { .. });

Arrays of Integration must be immediately wrapped in Promise.all

Error Code: Functionless(10017) Error Type: ERROR

Arrays of integrations within StepFunction, ExpressStepFunction must be immediately wrapped in Promise.all.

These services support concurrent invocation, but do not support manipulation of the references.

const func = new Function<string, string>(stack, 'func', async (input) => { return "hi" });

new StepFunction(stack, 'sfn, async () => {
// invalid
const f = [1,2].map(await () => func());
// valid
const ff = await Promise.all([1,2].map(await () => func()));
// valid
return Promise.all([1,2].map(await () => func()));
});

Some Resources like Function support synchronous or asynchronous handing of Integrations.

new Function(stack, 'func2', async () => {
// valid
const f = [1,2].map(await () => func())
const f2 = [1,2].map(await () => func());;
return Promise.all([...f, ...f2]);
});

In the case of Function, any valid NodeJS Promise feature is supported.


AwsMethod request must have exactly one integration call

Error Code: Functionless(10003) Error Type: ERROR

When using the AwsMethod, the request argument must be a function with exactly one integration call.

new AwsMethod(
{
httpMethod: "GET",
resource: api.root
},
($input) => {
return $AWS.DynamoDB.GetItem({ .. });
},
// etc.
)

Cannot perform all arithmetic on variables in Step Function

Error Code: Functionless(10000) Error Type: ERROR

Step Functions can only preform limited arithmetic operations.

Add (+), Subtract (-) and their duratives (+=, ++) are supported, but operations like multiply (*) and mod (%) are not.

// ok
new StepFunction(scope, id, () => 1 + 2);

// ok
new StepFunction(scope, id, (input: { num: number }) => input.number + 1);

// illegal!
new StepFunction(scope, id, (input: { num: number }) => input.number * 2);

To workaround, use a Function to implement the arithmetic expression. Be aware that this comes with added cost and operational risk.

const mult = new Function(scope, "add", (input: { a: number, b: number }) => input.a * input.b);

new StepFunction(scope, id, async (input: { num: number }) => {
await mult({a: input.number, b: 1});
});

Cannot use infrastructure Resource in Function closure

Error Code: Functionless(10009) Error Type: ERROR

Cannot use Infrastructure resource in Function closure.

The .resource property of Function, StepFunction, ExpressStepFunction, EventBus, and Table are not available in Native Function Closures.

const table = new Table(this, 'table', { ... });
new Function(this, 'func', async () => {
// valid use of a Table
const $AWS.DynamoDB.GetItem({
Table: table,
...
})
// invalid - .resource is not available
const index = table.resource.tableStreamArn;
});

Workaround 1 - Functionless Resource Properties

In many cases, common properties are available on the Functionless Resource, for example:

const table = new Table(this, 'table', { ... });
new Function(this, 'func', async () => {
const tableArn = table.tableArn;
});

Workaround 2 - Dereference

For some properties, referencing to a variable outside of the closure will work.

const table = new Table(this, 'table', { ... });
const tableStreamArn = table.resource.tableStreamArn;
new Function(this, 'func', async () => {
const tableStreamArn = tableStreamArn;
});

Workaround 3 - Environment Variable

Finally, if none of the above work, the lambda environment variables can be used.

const table = new Table(this, 'table', { ... });
new Function(this, 'func', {
environment: {
STREAM_ARN: table.resource.tableStreamArn
}
}, async () => {
const tableStreamArn = process.env.STREAM_ARN;
});

Classes are not yet supported by Functionless

Error Code: Functionless(10031) Error Type: ERROR

Classes, methods and private identifiers are not yet supported by Functionless.

To workaround, use Functions.

function foo () { .. }
const foo = () => { .. }

See

https://github.com/functionless/functionless/issues/362


Event Bridge does not support a truthy comparison

Error Code: Functionless(10032) Error Type: ERROR


EventBus Input Transformers do not support integrations

Error Code: Functionless(10014) Error Type: ERROR

EventBus Input Transformers do not support Integrations.

const func = new Function<string, string>(stack, 'func', async (input) => {
return axios.get(input);
})

// invalid
new EventBus(stack, 'bus').all().map(async event => ({ html: await func(event.detail.url) }));

Workaround - Send the event to a function.

const func = new Function<string, string>(stack, 'func', async (input) => {
return `transform${input}`;
})

// valid
new EventBus(stack, 'bus').all().pipe(new Function(stack, 'webpuller', async (event) => ({
html: await func(event.detail.url)
})));

EventBus Rules do not support integrations

Error Code: Functionless(10015) Error Type: ERROR

EventBus Rules do not support Integrations.

const validate = new Function<string, string>(stack, 'validate', async (input) => {
return axios.get(`https://mydomain/validate/${input}`);
})

// invalid
new EventBus(stack, 'bus').when(async (event) => await validate(input.detail.value)).pipe(...);

Workaround - Send the event to a function.

// valid
new EventBus(stack, 'bus').all().pipe(new Function(stack, 'webpuller', async (event) => {
if(await validate(event.source)) {
...
}
});

Expected an object literal

Error Code: Functionless(10012) Error Type: ERROR

Due to limitations in respective Functionless interpreters, it is often a requirement to specify an object literal instead of a variable reference.

const input = {
Table: table,
Key: {
// etc.
}
};
// invalid - input must be an object literal
$AWS.DynamoDB.GetItem(input)

To work around, ensure that you specify an object literal.

$AWS.DynamoDB.GetItem({
Table: table,
Key: {
// etc.
}
})

Function not compiled by Functionless plugin

Error Code: Functionless(10001) Error Type: ERROR

During CDK synth a function was encountered which was not compiled by the Functionless compiler plugin. This suggests that the plugin was not correctly configured for this project.

Ensure you follow the instructions at https://functionless.org/docs/getting-started.


Function closure serialization was not allowed to complete

Error Code: Functionless(10004) Error Type: ERROR

Lambda Function closure synthesis runs async, but CDK does not normally support async.

In order for the synthesis to complete successfully

  1. Use autoSynth new App({ authSynth: true }) or new App() with the CDK Cli (cdk synth)
  2. Use await asyncSynth(app) exported from Functionless in place of app.synth()
  3. Manually await on the closure serializer promises await Promise.all(Function.promises)

https://github.com/functionless/functionless/issues/128


Incorrect state machine type imported

Error Code: Functionless(10006) Error Type: ERROR

Incorrect State Machine Type Imported

Functionless StepFunctions are separated into ExpressStepFunction and StepFunction based on being aws_stepfunctions.StateMachineType.EXPRESS or aws_stepfunctions.StateMachineType.STANDARD respectively.

In order to ensure correct function of Functionless integrations, the correct import statement must be used.

const sfn = new aws_stepfunctions.StateMachine(scope, 'standardMachine', {...});
// valid
StateMachine.fromStepFunction(sfn);
// invalid - not an express machine
ExpressStateMachine.fromStepFunction(sfn);

const exprSfn = new aws_stepfunctions.StateMachine(scope, 'standardMachine', {
stateMachineType: aws_stepfunctions.StateMachineType.EXPRESS,
});
// valid
ExpressStateMachine.fromStepFunction(exprSfn);
// invalid - not a standard machine
StateMachine.fromStepFunction(exprSfn);

Integration must be immediately awaited or returned

Error Code: Functionless(10016) Error Type: ERROR

Integrations within StepFunction, ExpressStepFunction, AppsyncResolver, and AwsMethod must be immediately awaited or returned.

These services do not support references to asynchronous operations. In order to model an asynchronous call being handled synchronously, all integrations that return promises must be awaited or returned.

const func = new Function<string, string>(stack, 'func', async (input) => { return "hi" });

new StepFunction(stack, 'sfn', async () => {
// invalid
const f = func();
// valid
const ff = await func();
// valid
return func();
});

new AppsyncResolver(..., async () => {
// invalid
const f = func();
// valid
const ff = await func();
// valid
return func();
})

new AwsMethod(
...,
async () => {
// invalid
const f = func();
// valid
const ff = await func();
// valid
return func();
}
);

Some Resources like Function support synchronous or asynchronous handing of Integrations.

new Function(stack, 'func2' , async () => {
// valid
const f = func();
// valid
const ff = await func();
const fDone = await f;
// valid
return func();
});

In the case of Function, any valid NodeJS Promise feature is supported.


Invalid Input

Error Code: Functionless(10027) Error Type: ERROR

Invalid Input

Generic error code for when the user provided an unexpected input as documented and reflected in the types.

See the error message for more details.


StepFunction throw must be Error or StepFunctionError class

Error Code: Functionless(10030) Error Type: ERROR

Errors in Step Functions can only be thrown in one of two ways:

  1. by throwing javascript's Error class
throw Error("message");
throw new Error("message");
  1. by throwing the StepFunctionError class
throw new StepFunctionError("CustomErrorName", { error: "data" })

StepFunction invalid filter syntax

Error Code: Functionless(10034) Error Type: DEPRECATED

DEPRECATED - Step Function filter syntax contain the same limits as all other step function syntax.


StepFunctions Invalid collection access

Error Code: Functionless(10025) Error Type: ERROR

Step Functions - Invalid Collection access.

  1. Arrays can be accessed with numbers
  2. Objects can be accessed with strings
  3. Access Elements must be constant values - Step Functions does not support access using dynamic variables
const func = new Function(this, 'func', async () => { return { index: 0, elm: "a" }; });
new StepFunction(stack, 'sfn', () => {
const obj = { a: "val" };
// valid
obj.a;
// valid
obj["a"];
// invalid
obj[await func().elm];

const arr = [1];
// valid
arr[0]
// invalid
arr[await func().index];
});

Workaround - use Function

const accessor = new Function<{ obj: [key: string]: string, acc: string }, string>(
stack,
'func',
async (input) => {
return input.obj[input.acc];
}
);

new StepFunction(stack, 'sfn', () => {
// valid
await accessor(obj, a);
});

StepFunctions calls to EventBus putEvents must use object literals

Error Code: Functionless(10023) Error Type: ERROR

Events passed to an EventBus in a StepFunction must be one or more literal objects and may not use the spread (...) syntax or computed properties.

const sfn = new StepFunction(stack, "sfn", async () => {
const sourceName = "source";
const event = { source: "lambda", "detail-type": "type", detail: {} };
// invalid
await bus.putEvents(event);
// invalid
await bus.putEvents({ ...event });
// invalid
await bus.putEvents(...[event]);
// invalid
await bus.putEvents({
[sourceName]: "lambda",
"detail-type": "type",
detail: {},
});
// valid
await bus.putEvents({
source: "lambda",
"detail-type": "type",
detail: {},
});
});

Workaround - Function can be used to generate dynamic event collections.

const sender = new Function(stack, "sender", async (event) => {
const sourceName = "source";
const event = { source: "lambda", "detail-type": "type", detail: {} };
await bus.putEvents(event); // valid
await bus.putEvents({ ...event }); // valid
await bus.putEvents(...[event]); // valid
// valid
await bus.putEvents({
[sourceName]: "lambda",
"detail-type": "type",
detail: {},
});
// valid
await bus.putEvents({
source: "lambda",
"detail-type": "type",
detail: {},
});
});

const sfn = new StepFunction(stack, "sfn", async () => {
const event = { source: "lambda", "detail-type": "type", detail: {} };
await sender(event);
});

The limitation is due to Step Function's lack of optional or default value retrieval for fields. Attempting to access a missing field in ASL leads to en error. This can be fixed using Choice/Conditions to check for the existence of a single field, but would take all permutations of all optional fields to support optional field at runtime. Due to this limitation, we currently compute the transformation at compile time using the fields present on the literal object. For more details and process see: https://github.com/functionless/functionless/issues/101.


StepFunctions does not support destructuring object with rest

Error Code: Functionless(10033) Error Type: ERROR

Step Functions does not natively support dynamic object manipulation.

Due to this limitation, ...rest is not supported when destructuring objects.

new StepFunction(..., async () => {
const value = { a: "a", b: "b", c: "c" };
// valid
const { a, b } = value;
// invalid
const { a, b, ...rest } = value;
});

In the above example, we'd expect rest to look like { c: "c" }, but Step Functions Amazon States Language does not natively support a way to enumerate the fields of an object or delete fields from an object without first knowing all field names in an object.

Workaround - Explicit

If ...rest is being used as a convince, a work around is to just be explicit.

new StepFunction(..., async () => {
const value = { a: "a", b: "b", c: "c" };
// valid
const { a, b } = value;
// invalid
const rest = { c: value.c };
});

Workaround - Lambda

Sometimes ...rest is used as part of the program logic, for example, if some fields of an object are known while others are not or to remove known fields from an object.

const extractAAndB = new Function<
{ a: string; b: string; [key: string]: string },
{ a: string; b: string; rest: { [key: string]: string } }
>(stack, "func", async ({ a, b, ...rest }) => ({ a, b, rest }));
new StepFunction(..., async () => {
const value = { a: "a", b: "b", c: "c" };
// valid
const { a, b, rest } = await extractAAndB(value);
});

StepFunctions error cause must be a constant

Error Code: Functionless(10024) Error Type: ERROR

StepFunctions supports throwing errors with causes, however those errors do not support dynamic values.

https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-fail-state.html

new StepFunction<{ value: undefined }, void>(this, 'sfn', async (input) => {
// invalid - the error cause is not constant
throw new Error(input.value);
});

Workaround - Return with the error message encoded in payload and let the machine succeed.

new StepFunction<{ value: undefined }, { error?: string }>(this, 'sfn', async (input) => {
// valid
return {
error: input.value
}
});

StepFunctions mismatched index type.

Error Code: Functionless(10035) Error Type: WARN

StepFunctions could fail at runtime with mismatched index types.

Javascript and Typescript support the normalization object property access and array access when the index is a number or number as a string.

Unfortunately SFN cannot repeat this normalization in an inexpensive way (ex: checking all property access for correctness at runtime).

The below is all valid typescript.

new StepFunction(stack, 'sfn', async () => {
const obj = {1: "value"};
const arr = [1];

// invalid - numeric object property access in SFN is invalid, key must be a string
obj[1];

// invalid - string array access in SFN is invalid, index must be a number
arr["0"];

// valid
obj["1"];
// valid
arr[0];
});

StepFunction property names must be constant

Error Code: Functionless(10026) Error Type: ERROR

StepFunctions does not support dynamic property names

new StepFunction(stack, 'sfn', async () => { const c = "c"; const { a: "valid",

  ["b"]: "valid",
[c]: "invalid",
[someMethod()] :"invalid"

} });

Workaround - use Function

const assign = new Function<{ obj: { [key: string]: string }, key: string, value: string }>(stack, 'func', async (input) => { return { ...input.obj,

   [input.key]: input.value
}

}); new StepFunction(stack, 'sfn', async () => { return await assign({}, someMethod(), "value"); })


Step Function Retry Invalid Input.

Error Code: Functionless(10037) Error Type: ERROR

Step Function Retry Invalid Input.

$SFN.Retry can either retry on all errors or be given a constant, array of literal objects (Retry) that determine which errors to retry on. The array must have 1 or more literal Retry objects.

new StepFunction(stack, "sfn", async ()=> {
// Valid
await $SFN.retry(async () => func());
// Valid
await $SFN.retry([{ ErrorEquals: ["States.Timeout"] }], async () => func());
// Valid
await $SFN.retry([{ ErrorEquals: ["States.Timeout"], MaxAttempts: 5, IntervalSeconds: 2, BackoffRate: 0.5 }], async () => func());
// Valid
await $SFN.retry([{ ErrorEquals: ["States.Timeout"] }, { ErrorEquals: ["Lambda.TooManyRequestsException"] }], async () => func());

// Invalid - reference to retry objects
await $SFN.retry(myRetryObjects, async () => func());
// Invalid - reference to a retry object
await $SFN.retry([retryObject], async () => func());
// Invalid - reference to a error name
await $SFN.retry([{ ErrorEquals: [ myErrorType ] }], async () => func());
// Invalid - array is empty
await $SFN.retry([], async () => func());
})

The limitation is due to Step Function's lack of support for dynamic paths (json paths) for retry configuration.

https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error


Step Functions Arithmetic Only Supports Integers

Error Code: Functionless(10038) Error Type: WARN

Step Functions Arithmetic Only Supports Integer

Step Functions only supports integer addition via the States.MathAdd.

new StepFunction(stack, "sfn", async (input: { a: number }) => {
return 1.5 + input.a;
});

If the above machine is given input: { a: 0.5 }, the result will be 1.

Effectively resulting in: 1.5 + 0.5 === 1

Workaround:

Do floating point math within a lambda function.

const floatingPointAdd = new Function(stack, "fn", async (input: { a: number, b: number }) => {
return input.a + input.b;
});
new StepFunction(stack, "sfn", async (input: { a: number }) => {
return floatingPointAdd(1.5, input.a);
});

Step Functions does not support undefined

Error Code: Functionless(10022) Error Type: ERROR

Step Functions does not support undefined

In Step Functions, a property cannot be undefined when assigned to an object or passed into a state.

For consistency, undefined is not allowed anytime a value is returned, for example in a ternary expression (x ? undefined : value). The undefined literal is allowed for comparison. if(x === undefined){}.

const func = new Function(stack, 'func', () => { return undefined; })
new StepFunction<{ val: string | undefined }, undefined>(stack, 'sfn', async (input) => {
const v = {
// invalid - could be undefined
val: input.val
}

// invalid
v ? undefined : "a"

// invalid, function outputs undefined.
const output = await func();

// invalid - could be undefined
return input.val;
});
  1. Workaround - use null instead of undefined

    • const func = new Function(stack, 'func', () => { return null; })
      new StepFunction<{ val: string | null }, null>(stack, 'sfn', async () => {
      const v = {
      // valid
      val: null
      }

      // valid
      v ? null : "a"

      // valid, function outputs undefined.
      const output = await func();

      // valid
      return null;
      });

2. Workaround - resolve undefined to null or a value before assignment

* ```ts
const func = new Function(stack, 'func', () => { return undefined; })
new StepFunction<{ val: string | undefined }, null>(stack, 'sfn', async (undefined) => {
const v = {
// valid - could replace null with any defined value
val: input.val ?? null
}

// valid - could replace null with any defined value
const output = (await func()) ?? null;

// valid - could replace null with any defined value
return input.val ?? null;
});
  1. Workaround - check for undefined
const func = new Function(stack, 'func', () => { return { val: undefined }; })
new StepFunction<{ val: string | undefined }, null>(stack, 'sfn', async (undefined) => {
let v;
if(input.val) {
v = {
val: input.val
}
} else {
v = {}
}

// valid - could replace null with any defined value
const output = await func();
const val = output ? output : null;

// valid - could replace null with any defined value
if(input.val) {
return input.val;
}
return null;
});

Unable to find reference out of application function

Error Code: Functionless(10019) Error Type: ERROR

Unable to find reference out of application function.

Functionless processes your application code to find infrastructure references, wire up permissions, build clients, and more. All infrastructure must be created outside of your application logic closures. References to those resources (Integrations) must be traceable back to their location outside of your application functions.

const func = new Function(...);

new Function(stack, 'id', {
// valid
func();
const f = func();
// valid
f();
const a = { f };
// valid
a.f();
// and more
})

Functionless attempts to handle all valid typescript referencing scenarios, but some may be missed.

If this error is thrown and the reference should be valid, please create an issue.


Unexpected Error

Error Code: Functionless(10005) Error Type: ERROR

Generic error message to denote errors that should not happen and are not the fault of the Functionless library consumer.

Please report this issue.


Unsafe use of secrets

Error Code: Functionless(10007) Error Type: ERROR

Unsafe usage of Secrets.

The use of secrets is unsafe or not supported by Functionless.

See

https://github.com/functionless/functionless/issues/252 to track supported secret patterns.


Unsupported AWS SDK in Resource.

Error Code: Functionless(10036) Error Type: ERROR

The AWS SDK being used in the current resource is unsupported by that resource.

Workaround:

Most of the ASK APIs will work within


Unsupported feature

Error Code: Functionless(10021) Error Type: ERROR

Unsupported Feature

Generic error for unsupported features.

See error message provided for more details.


Unsupported use of Promises

Error Code: Functionless(10018) Error Type: ERROR

Unsupported use of Promises

In StepFunction and ExpressStepFunction, Promise.all can be used to turn an array of promises into a single promise. However, it must directly wrap a method which returns an array of promises.

const func = new Function(stack, id, async () => {});

new StepFunction(stack, id, async () => {
const c = [1,2];
// invalid
const p = await Promise.all(c);
// valid
const t = await Promise.all([1,2].map(i => func()));
});

AppsyncResolver and AppsyncField do not support Promise.all or arrays of Promises. AWS App Sync does not support concurrent or dynamic invocation of integrations.

const func = new Function(stack, id, async () => {});

new AppsyncResolver(..., async ($context) => {
// valid - series of integration invocations
const t = await func();
const tt = await func();
// invalid - concurrent invocation
const arr = await Promise.all([1,2].map(() => func()));
// invalid - dynamic invocation
const arr = await Promise.all($context.arguments.arr.map(() => func()));
});

Unsupported initialization of Resources in a runtime closure

Error Code: Functionless(10008) Error Type: ERROR

Unsupported initialization of Resources in a Function closure

  1. Valid - EventBus resource is created outside of the closure.
const bus = new EventBus(this, 'bus');
const function = new Function(this, 'func', () => {
bus.putEvents(...);
});
  1. Invalid - EventBus resource is created in the closure.
const function = new Function(this, 'func', () => {
new EventBus(this, 'bus').putEvents(...);
});
  1. Invalid - EventBus resource is created in a method called by the closure.
function bus() {
return new EventBus(this, 'bus');
}
const function = new Function(this, 'func', () => {
bus().putEvents(...);
});
  1. Valid - EventBus resource is created outside of the closure and called methods.
const bus = new EventBus(this, 'bus');
function bus() {
return bus;
}
const function = new Function(this, 'func', () => {
bus().putEvents(...);
});