Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lambda): improve validation errors for lambda functions #32323

Merged
merged 2 commits into from
Dec 7, 2024

Conversation

mrgrain
Copy link
Contributor

@mrgrain mrgrain commented Nov 28, 2024

Issue # (if applicable)

Relates to #32324

Reason for this change

Currently all errors are untyped. This makes it difficult users to programmatically distinguish between different classes of errors, e.g. what is a validation error vs what is a syntax error? With this change, users can catch errors and check their type before proceeding accordingly.

Description of changes

Addition of a new Error type ValidationError. For now this error is used only in a single file. The intention is to extend this to all error cases. ValidationError extends an abstract ConstructError which also handles any improvements to error display.

ConstructError manipulates the stack trace to improve display. It's changing two things, both of which are based on a construct that is passed in on error creation. If not construct is passed, the error behaves as before.

  1. Construct information is inserted as the first line of the stack trace.
  2. The strack trace is captured from the point of creation of the construct. That is the class constructor call. This is achieved by passing the error's constructs into Error.captureStackTrace. As a side effect, in many cases the "line of error" is not minified code anymore and thus doesn't ruin the error experience for users.

See comments for current vs future errors.

Description of how you validated changes

Existing test. Manual testing of error cases.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@mrgrain mrgrain requested a review from a team as a code owner November 28, 2024 18:08
@aws-cdk-automation aws-cdk-automation requested a review from a team November 28, 2024 18:08
@github-actions github-actions bot added the p2 label Nov 28, 2024
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Nov 28, 2024
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.

Copy link

codecov bot commented Nov 28, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 78.67%. Comparing base (609faba) to head (3958233).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #32323   +/-   ##
=======================================
  Coverage   78.67%   78.67%           
=======================================
  Files         107      107           
  Lines        7237     7237           
  Branches     1329     1329           
=======================================
  Hits         5694     5694           
  Misses       1357     1357           
  Partials      186      186           
Flag Coverage Δ
suite.unit 78.67% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
packages/aws-cdk 78.67% <ø> (ø)

@mrgrain mrgrain force-pushed the mrgrain/feat/improved-validation-errors-lambda branch 2 times, most recently from 60dded3 to dc41aea Compare November 29, 2024 11:39
@mrgrain mrgrain changed the title feat: improve validation errors for lambda functions feat(lambda): improve validation errors for lambda functions Nov 29, 2024
@mrgrain mrgrain added pr-linter/exempt-readme The PR linter will not require README changes pr-linter/exempt-integ-test The PR linter will not require integ test changes labels Nov 29, 2024
@mrgrain mrgrain changed the title feat(lambda): improve validation errors for lambda functions fix(lambda): improve validation errors for lambda functions Nov 29, 2024
@mrgrain
Copy link
Contributor Author

mrgrain commented Nov 29, 2024

exempted from readme and integ tests since these are covered by existing test cases.

@aws-cdk-automation aws-cdk-automation dismissed stale reviews from themself November 29, 2024 12:13

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Nov 29, 2024
@mrgrain mrgrain force-pushed the mrgrain/feat/improved-validation-errors-lambda branch from dc41aea to fe9406b Compare November 30, 2024 11:56
@mrgrain
Copy link
Contributor Author

mrgrain commented Nov 30, 2024

Error currently in Python:

jsii.errors.JavaScriptError: 
  Error: Function name can not be longer than 64 characters but has 140 characters.
      at new Function (/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/jsii-kernel-CbXDJ6/node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:8425)
      at Kernel._Kernel_create (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpmo6tk7k9/lib/program.js:9127:25)
      at Kernel.create (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpmo6tk7k9/lib/program.js:8798:93)
      at KernelHost.processRequest (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpmo6tk7k9/lib/program.js:10715:36)
      at KernelHost.run (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpmo6tk7k9/lib/program.js:10675:22)
      at Immediate._onImmediate (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpmo6tk7k9/lib/program.js:10676:46)
      at process.processImmediate (node:internal/timers:478:21)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/code/app.py", line 10, in <module>
    CdkbadpythonStack(app, "CdkbadpythonStack",
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/cdkbadpython/cdkbadpython_stack.py", line 12, in __init__
    lamb.Function(
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/aws_cdk/aws_lambda/__init__.py", line 27904, in __init__
    jsii.create(self.__class__, self, [scope, id, props])
  File "/Users/user/code.venv/lib/python3.11/site-packages/jsii/_kernel/__init__.py", line 334, in create
    response = self.provider.create(
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 365, in create
    return self._process.send(request, CreateResponse)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 342, in send
    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Function name can not be longer than 64 characters but has 140 characters.
Subprocess exited with error 1

@mrgrain mrgrain force-pushed the mrgrain/feat/improved-validation-errors-lambda branch from fe9406b to 980516a Compare November 30, 2024 12:09
@mrgrain
Copy link
Contributor Author

mrgrain commented Nov 30, 2024

New error in Python:

jsii.errors.JavaScriptError: 
  ValidationError: Function name can not be longer than 64 characters but has 140 characters.
      at path [CdkbadpythonStack/PythonLambda] in aws-cdk-lib.aws_lambda.Function
  
      at Kernel._Kernel_create (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpz4dfbcv2/lib/program.js:9127:25)
      at Kernel.create (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpz4dfbcv2/lib/program.js:8798:93)
      at KernelHost.processRequest (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpz4dfbcv2/lib/program.js:10715:36)
      at KernelHost.run (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpz4dfbcv2/lib/program.js:10675:22)
      at Immediate._onImmediate (/private/var/folders/7x/8b8nc92x7mg8ygtfd52kf08r0000gq/T/tmpz4dfbcv2/lib/program.js:10676:46)
      at process.processImmediate (node:internal/timers:478:21)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/code/app.py", line 10, in <module>
    CdkbadpythonStack(app, "CdkbadpythonStack",
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/cdkbadpython/cdkbadpython_stack.py", line 12, in __init__
    lamb.Function(
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/aws_cdk/aws_lambda/__init__.py", line 24569, in __init__
    jsii.create(self.__class__, self, [scope, id, props])
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_kernel/__init__.py", line 334, in create
    response = self.provider.create(
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 365, in create
    return self._process.send(request, CreateResponse)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 342, in send
    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Function name can not be longer than 64 characters but has 140 characters.
Subprocess exited with error 1

@mrgrain
Copy link
Contributor Author

mrgrain commented Nov 30, 2024

Error currently in TypeScript: (yes that is correct)

Note that in an actual console, the minified code line will appear as about 5 pages of scrambled code and 5 pages of whitespace to render the ^.

/Users/user/code/node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1
"use strict";var _a,_b;Object.defineProperty(exports,"__esModule",{value:!0}),exports.FunctionVersionUpgrade=exports.verifyCodeConfig=exports.Function=exports.RecursiveLoop=exports.LoggingFormat=exports.LogFormat=exports.ApplicationLogLevel=exports.SystemLogLevel=exports.Tracing=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var adot_layers_1=()=>{var tmp=require("./adot-layers");return adot_layers_1=()=>tmp,tmp},architecture_1=()=>{var tmp=require("./architecture");return architecture_1=()=>tmp,tmp},function_base_1=()=>{var tmp=require("./function-base");return function_base_1=()=>tmp,tmp},function_hash_1=()=>{var tmp=require("./function-hash");return function_hash_1=()=>tmp,tmp},handler_1=()=>{var tmp=require("./handler");return handler_1=()=>tmp,tmp},lambda_version_1=()=>{var tmp=require("./lambda-version");return lambda_version_1=()=>tmp,tmp},lambda_generated_1=()=>{var tmp=require("./lambda.generated");return lambda_generated_1=()=>tmp,tmp},layers_1=()=>{var tmp=require("./layers");return layers_1=()=>tmp,tmp},runtime_1=()=>{var tmp=require("./runtime");return runtime_1=()=>tmp,tmp},util_1=()=>{var tmp=require("./util");return util_1=()=>tmp,tmp},cloudwatch=()=>{var tmp=require("../../aws-cloudwatch");return cloudwatch=()=>tmp,tmp},aws_codeguruprofiler_1=()=>{var tmp=require("../../aws-codeguruprofiler");return aws_codeguruprofiler_1=()=>tmp,tmp},ec2=()=>{var tmp=require("../../aws-ec2");return ec2=()=>tmp,tmp},efs=()=>{var tmp=require("../../aws-efs");return efs=()=>tmp,tmp},iam=()=>{var tmp=require("../../aws-iam");return iam=()=>tmp,tmp},logs=()=>{var tmp=require("../../aws-logs");return logs=()=>tmp,tmp},sqs=()=>{var tmp=require("../../aws-sqs");return sqs=()=>tmp,tmp},core_1=()=>{var tmp=require("../../core");return core_1=()=>tmp,tmp},cx_api_1=()=>{var tmp=require("../../cx-api");return cx_api_1=()=>tmp,tmp},Tracing;(function(Tracing2){Tracing2.ACTIVE="Active",Tracing2.PASS_THROUGH="PassThrough",Tracing2.DISABLED="Disabled"})(Tracing||(exports.Tracing=Tracing={}));var SystemLogLevel;(function(SystemLogLevel2){SystemLogLevel2.INFO="INFO",SystemLogLevel2.DEBUG="DEBUG",SystemLogLevel2.WARN="WARN"})(SystemLogLevel||(exports.SystemLogLevel=SystemLogLevel={}));var ApplicationLogLevel;(function(ApplicationLogLevel2){ApplicationLogLevel2.INFO="INFO",ApplicationLogLevel2.DEBUG="DEBUG",ApplicationLogLevel2.WARN="WARN",ApplicationLogLevel2.TRACE="TRACE",ApplicationLogLevel2.ERROR="ERROR",ApplicationLogLevel2.FATAL="FATAL"})(ApplicationLogLevel||(exports.ApplicationLogLevel=ApplicationLogLevel={}));var LogFormat;(function(LogFormat2){LogFormat2.TEXT="Text",LogFormat2.JSON="JSON"})(LogFormat||(exports.LogFormat=LogFormat={}));var LoggingFormat;(function(LoggingFormat2){LoggingFormat2.TEXT="Text",LoggingFormat2.JSON="JSON"})(LoggingFormat||(exports.LoggingFormat=LoggingFormat={}));var RecursiveLoop;(function(RecursiveLoop2){RecursiveLoop2.ALLOW="Allow",RecursiveLoop2.TERMINATE="Terminate"})(RecursiveLoop||(exports.RecursiveLoop=RecursiveLoop={}));class Function extends function_base_1().FunctionBase{get currentVersion(){if(this._currentVersion)return this._currentVersion;this._warnIfCurrentVersionCalled&&this.warnInvokeFunctionPermissions(this),this._currentVersion=new(lambda_version_1()).Version(this,"CurrentVersion",{lambda:this,...this.currentVersionOptions});const cfn=this._currentVersion.node.defaultChild,originalLogicalId=this.stack.resolve(cfn.logicalId);return cfn.overrideLogicalId(core_1().Lazy.uncachedString({produce:()=>{const hash=(0,function_hash_1().calculateFunctionHash)(this,this.hashMixins.join(""));return`${(0,function_hash_1().trimFromStart)(originalLogicalId,223)}${hash}`}})),this._currentVersion}get resourceArnsForGrantInvoke(){return[this.functionArn,`${this.functionArn}:*`]}static classifyVersionProperty(propertyName,locked){this._VER_PROPS[propertyName]=locked}static fromFunctionName(scope,id,functionName){return Function.fromFunctionAttributes(scope,id,{functionArn:core_1().Stack.of(scope).formatArn({service:"lambda",resource:"function",resourceName:functionName,arnFormat:core_1().ArnFormat.COLON_RESOURCE_NAME}),sameEnvironment:!0})}static fromFunctionArn(scope,id,functionArn){return Function.fromFunctionAttributes(scope,id,{functionArn})}static fromFunctionAttributes(scope,id,attrs){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_lambda_FunctionAttributes(attrs)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.fromFunctionAttributes),error}const functionArn=attrs.functionArn,functionName=extractNameFromArn(attrs.functionArn),role=attrs.role;class Import extends function_base_1().FunctionBase{constructor(s,i){super(s,i,{environmentFromArn:functionArn}),this.functionName=functionName,this.functionArn=functionArn,this.role=role,this.permissionsNode=this.node,this.architecture=attrs.architecture??architecture_1().Architecture.X86_64,this.resourceArnsForGrantInvoke=[this.functionArn,`${this.functionArn}:*`],this.canCreatePermissions=attrs.sameEnvironment??this._isStackAccount(),this._skipPermissions=attrs.skipPermissions??!1,this.grantPrincipal=role||new(iam()).UnknownPrincipal({resource:this}),attrs.securityGroup?this._connections=new(ec2()).Connections({securityGroups:[attrs.securityGroup]}):attrs.securityGroupId&&(this._connections=new(ec2()).Connections({securityGroups:[ec2().SecurityGroup.fromSecurityGroupId(scope,"SecurityGroup",attrs.securityGroupId)]}))}}return new Import(scope,id)}static metricAll(metricName,props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAll),error}return new(cloudwatch()).Metric({namespace:"AWS/Lambda",metricName,...props})}static metricAllErrors(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllErrors),error}return this.metricAll("Errors",{statistic:"sum",...props})}static metricAllDuration(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllDuration),error}return this.metricAll("Duration",props)}static metricAllInvocations(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllInvocations),error}return this.metricAll("Invocations",{statistic:"sum",...props})}static metricAllThrottles(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllThrottles),error}return this.metricAll("Throttles",{statistic:"sum",...props})}static metricAllConcurrentExecutions(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllConcurrentExecutions),error}return this.metricAll("ConcurrentExecutions",{statistic:"max",...props})}static metricAllUnreservedConcurrentExecutions(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_cloudwatch_MetricOptions(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.metricAllUnreservedConcurrentExecutions),error}return this.metricAll("UnreservedConcurrentExecutions",{statistic:"max",...props})}constructor(scope,id,props){super(scope,id,{physicalName:props.functionName}),this.permissionsNode=this.node,this.canCreatePermissions=!0,this._layers=[],this.environment={},this.hashMixins=new Array;try{jsiiDeprecationWarnings().aws_cdk_lib_aws_lambda_FunctionProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,Function),error}if(props.functionName&&!core_1().Token.isUnresolved(props.functionName)){if(props.functionName.length>64)throw new Error(`Function name can not be longer than 64 characters but has ${props.functionName.length} characters.`);if(!/^[a-zA-Z0-9-_]+$/.test(props.functionName))throw new Error(`Function name ${props.functionName} can contain only letters, numbers, hyphens, or underscores with no spaces.`)}if(props.description&&!core_1().Token.isUnresolved(props.description)&&props.description.length>256)throw new Error(`Function description can not be longer than 256 characters but has ${props.description.length} characters.`);const managedPolicies=new Array;if(managedPolicies.push(iam().ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")),props.vpc&&managedPolicies.push(iam().ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole")),this.role=props.role||new(iam()).Role(this,"ServiceRole",{assumedBy:new(iam()).ServicePrincipal("lambda.amazonaws.com"),managedPolicies}),this.grantPrincipal=this.role,props.filesystem){const config=props.filesystem.config;if(!core_1().Token.isUnresolved(config.localMountPath)){if(!/^\/mnt\/[a-zA-Z0-9-_.]+$/.test(config.localMountPath))throw new Error(`Local mount path should match with ^/mnt/[a-zA-Z0-9-_.]+$ but given ${config.localMountPath}.`);if(config.localMountPath.length>160)throw new Error(`Local mount path can not be longer than 160 characters but has ${config.localMountPath.length} characters.`)}config.policies&&config.policies.forEach(p=>{this.role?.addToPrincipalPolicy(p)})}for(const statement of props.initialPolicy||[])this.role.addToPrincipalPolicy(statement);const code=props.code.bind(this);verifyCodeConfig(code,props);let profilingGroupEnvironmentVariables={};if(props.profilingGroup&&props.profiling!==!1)this.validateProfiling(props),props.profilingGroup.grantPublish(this.role),profilingGroupEnvironmentVariables={AWS_CODEGURU_PROFILER_GROUP_NAME:props.profilingGroup.profilingGroupName,AWS_CODEGURU_PROFILER_TARGET_REGION:props.profilingGroup.env.region,AWS_CODEGURU_PROFILER_GROUP_ARN:props.profilingGroup.profilingGroupArn,AWS_CODEGURU_PROFILER_ENABLED:"TRUE"};else if(props.profiling){this.validateProfiling(props);const profilingGroup=new(aws_codeguruprofiler_1()).ProfilingGroup(this,"ProfilingGroup",{computePlatform:aws_codeguruprofiler_1().ComputePlatform.AWS_LAMBDA});profilingGroup.grantPublish(this.role),profilingGroupEnvironmentVariables={AWS_CODEGURU_PROFILER_GROUP_NAME:profilingGroup.profilingGroupName,AWS_CODEGURU_PROFILER_TARGET_REGION:profilingGroup.env.region,AWS_CODEGURU_PROFILER_GROUP_ARN:profilingGroup.profilingGroupArn,AWS_CODEGURU_PROFILER_ENABLED:"TRUE"}}const env={...profilingGroupEnvironmentVariables,...props.environment};for(const[key,value]of Object.entries(env))this.addEnvironment(key,value);const dlqTopicOrQueue=this.buildDeadLetterQueue(props);dlqTopicOrQueue!==void 0&&(this.isQueue(dlqTopicOrQueue)?this.deadLetterQueue=dlqTopicOrQueue:this.deadLetterTopic=dlqTopicOrQueue);let fileSystemConfigs;if(props.filesystem&&(fileSystemConfigs=[{arn:props.filesystem.config.arn,localMountPath:props.filesystem.config.localMountPath}]),props.architecture&&props.architectures!==void 0)throw new Error("Either architecture or architectures must be specified but not both.");if(props.architectures&&props.architectures.length>1)throw new Error("Only one architecture must be specified.");if(this._architecture=props.architecture??(props.architectures&&props.architectures[0]),props.ephemeralStorageSize&&!props.ephemeralStorageSize.isUnresolved()&&(props.ephemeralStorageSize.toMebibytes()<512||props.ephemeralStorageSize.toMebibytes()>10240))throw new Error(`Ephemeral storage size must be between 512 and 10240 MB, received ${props.ephemeralStorageSize}.`);const resource=new(lambda_generated_1()).CfnFunction(this,"Resource",{functionName:this.physicalName,description:props.description,code:{s3Bucket:code.s3Location&&code.s3Location.bucketName,s3Key:code.s3Location&&code.s3Location.objectKey,s3ObjectVersion:code.s3Location&&code.s3Location.objectVersion,zipFile:code.inlineCode,imageUri:code.image?.imageUri},layers:core_1().Lazy.list({produce:()=>this.renderLayers()}),handler:props.handler===handler_1().Handler.FROM_IMAGE?void 0:props.handler,timeout:props.timeout&&props.timeout.toSeconds(),packageType:props.runtime===runtime_1().Runtime.FROM_IMAGE?"Image":void 0,runtime:props.runtime===runtime_1().Runtime.FROM_IMAGE?void 0:props.runtime.name,role:this.role.roleArn,environment:core_1().Lazy.uncachedAny({produce:()=>this.renderEnvironment()}),memorySize:props.memorySize,ephemeralStorage:props.ephemeralStorageSize?{size:props.ephemeralStorageSize.toMebibytes()}:void 0,vpcConfig:this.configureVpc(props),deadLetterConfig:this.buildDeadLetterConfig(dlqTopicOrQueue),reservedConcurrentExecutions:props.reservedConcurrentExecutions,imageConfig:undefinedIfNoKeys({command:code.image?.cmd,entryPoint:code.image?.entrypoint,workingDirectory:code.image?.workingDirectory}),kmsKeyArn:props.environmentEncryption?.keyArn,fileSystemConfigs,codeSigningConfigArn:props.codeSigningConfig?.codeSigningConfigArn,architectures:this._architecture?[this._architecture.name]:void 0,runtimeManagementConfig:props.runtimeManagementMode?.runtimeManagementConfig,snapStart:this.configureSnapStart(props),loggingConfig:this.getLoggingConfig(props),recursiveLoop:props.recursiveLoop});if((props.tracing!==void 0||props.adotInstrumentation!==void 0)&&(resource.tracingConfig=this.buildTracingConfig(props.tracing??Tracing.ACTIVE)),this._logGroup=props.logGroup,resource.node.addDependency(this.role),this.functionName=this.getResourceNameAttribute(resource.ref),this.functionArn=this.getResourceArnAttribute(resource.attrArn,{service:"lambda",resource:"function",resourceName:this.physicalName,arnFormat:core_1().ArnFormat.COLON_RESOURCE_NAME}),this.runtime=props.runtime,this.timeout=props.timeout,this.architecture=props.architecture??architecture_1().Architecture.X86_64,props.layers){if(props.runtime===runtime_1().Runtime.FROM_IMAGE)throw new Error("Layers are not supported for container image functions");this.addLayers(...props.layers)}for(const event of props.events||[])this.addEventSource(event);if(props.logRetention){if(props.logGroup)throw new Error("CDK does not support setting logRetention and logGroup");const logRetention=new(logs()).LogRetention(this,"LogRetention",{logGroupName:`/aws/lambda/${this.functionName}`,retention:props.logRetention,role:props.logRetentionRole,logRetentionRetryOptions:props.logRetentionRetryOptions});this._logGroup=logs().LogGroup.fromLogGroupArn(this,"LogGroup",logRetention.logGroupArn),this._logRetention=logRetention}if(props.code.bindToResource(resource),(props.onFailure||props.onSuccess||props.maxEventAge||props.retryAttempts!==void 0)&&this.configureAsyncInvoke({onFailure:props.onFailure,onSuccess:props.onSuccess,maxEventAge:props.maxEventAge,retryAttempts:props.retryAttempts}),this.currentVersionOptions=props.currentVersionOptions,props.filesystem){if(!props.vpc)throw new Error("Cannot configure 'filesystem' without configuring a VPC.");const config=props.filesystem.config;config.dependency&&this.node.addDependency(...config.dependency),this.connections.securityGroups.forEach(sg=>{sg.node.findAll().forEach(child=>{child instanceof core_1().CfnResource&&child.cfnResourceType==="AWS::EC2::SecurityGroupEgress"&&resource.node.addDependency(child)})}),config.connections?.securityGroups.forEach(sg=>{sg.node.findAll().forEach(child=>{child instanceof core_1().CfnResource&&child.cfnResourceType==="AWS::EC2::SecurityGroupIngress"&&resource.node.addDependency(child)})})}this.configureLambdaInsights(props),this.configureAdotInstrumentation(props),this.configureParamsAndSecretsExtension(props)}addEnvironment(key,value,options){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_lambda_EnvironmentOptions(options)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addEnvironment),error}if(["_HANDLER","_X_AMZN_TRACE_ID","AWS_DEFAULT_REGION","AWS_REGION","AWS_EXECUTION_ENV","AWS_LAMBDA_FUNCTION_NAME","AWS_LAMBDA_FUNCTION_MEMORY_SIZE","AWS_LAMBDA_FUNCTION_VERSION","AWS_LAMBDA_INITIALIZATION_TYPE","AWS_LAMBDA_LOG_GROUP_NAME","AWS_LAMBDA_LOG_STREAM_NAME","AWS_ACCESS_KEY","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","AWS_LAMBDA_RUNTIME_API","LAMBDA_TASK_ROOT","LAMBDA_RUNTIME_DIR"].includes(key))throw new Error(`${key} environment variable is reserved by the lambda runtime and can not be set manually. See https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html`);return this.environment[key]={value,...options},this}getLoggingConfig(props){if(props.logFormat&&props.loggingFormat)throw new Error("Only define LogFormat or LoggingFormat, not both.");if(props.applicationLogLevel&&props.applicationLogLevelV2)throw new Error("Only define applicationLogLevel or applicationLogLevelV2, not both.");if(props.systemLogLevel&&props.systemLogLevelV2)throw new Error("Only define systemLogLevel or systemLogLevelV2, not both.");if(props.applicationLogLevel||props.applicationLogLevelV2||props.systemLogLevel||props.systemLogLevelV2){if(props.logFormat!==LogFormat.JSON&&props.loggingFormat===void 0)throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LogFormat to '${LogFormat.JSON}', got '${props.logFormat}'.`);if(props.loggingFormat!==LoggingFormat.JSON&&props.logFormat===void 0)throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LoggingFormat to '${LoggingFormat.JSON}', got '${props.loggingFormat}'.`)}let loggingConfig;if(props.logFormat||props.logGroup||props.loggingFormat)return loggingConfig={logFormat:props.logFormat||props.loggingFormat,systemLogLevel:props.systemLogLevel||props.systemLogLevelV2,applicationLogLevel:props.applicationLogLevel||props.applicationLogLevelV2,logGroup:props.logGroup?.logGroupName},loggingConfig}invalidateVersionBasedOn(x){if(core_1().Token.isUnresolved(x))throw new Error("invalidateVersionOn: input may not contain unresolved tokens");this.hashMixins.push(x)}addLayers(...layers){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_lambda_ILayerVersion(layers)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addLayers),error}for(const layer of layers){if(this._layers.length===5)throw new Error("Unable to add layer: this lambda function already uses 5 layers.");if(layer.compatibleRuntimes&&!layer.compatibleRuntimes.find(runtime=>runtime.runtimeEquals(this.runtime))){const runtimes=layer.compatibleRuntimes.map(runtime=>runtime.name).join(", ");throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`)}this._layers.push(layer)}}addVersion(name,codeSha256,description,provisionedExecutions,asyncInvokeConfig={}){return new(lambda_version_1()).Version(this,"Version"+name,{lambda:this,codeSha256,description,provisionedConcurrentExecutions:provisionedExecutions,...asyncInvokeConfig})}addAlias(aliasName,options){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_lambda_AliasOptions(options)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addAlias),error}return(0,util_1().addAlias)(this,this.currentVersion,aliasName,options)}get logGroup(){if(!this._logGroup){const logRetention=new(logs()).LogRetention(this,"LogRetention",{logGroupName:`/aws/lambda/${this.functionName}`,retention:logs().RetentionDays.INFINITE});this._logGroup=logs().LogGroup.fromLogGroupArn(this,`${this.node.id}-LogGroup`,logRetention.logGroupArn)}return this._logGroup}_checkEdgeCompatibility(){const envEntries=Object.entries(this.environment);for(const[key,config]of envEntries)config.removeInEdge&&(delete this.environment[key],core_1().Annotations.of(this).addInfo(`Removed ${key} environment variable for Lambda@Edge compatibility`));const envKeys=Object.keys(this.environment);if(envKeys.length!==0)throw new Error(`The function ${this.node.path} contains environment variables [${envKeys}] and is not compatible with Lambda@Edge. Environment variables can be marked for removal when used in Lambda@Edge by setting the 'removeInEdge' property in the 'addEnvironment()' API.`)}configureLambdaInsights(props){props.insightsVersion!==void 0&&(props.runtime!==runtime_1().Runtime.FROM_IMAGE&&this.addLayers(layers_1().LayerVersion.fromLayerVersionArn(this,"LambdaInsightsLayer",props.insightsVersion._bind(this,this).arn)),this.role?.addManagedPolicy(iam().ManagedPolicy.fromAwsManagedPolicyName("CloudWatchLambdaInsightsExecutionRolePolicy")))}configureAdotInstrumentation(props){if(props.adotInstrumentation!==void 0){if(props.runtime===runtime_1().Runtime.FROM_IMAGE)throw new Error("ADOT Lambda layer can't be configured with container image package type");if(this.runtime===runtime_1().Runtime.GO_1_X)throw new Error("Runtime go1.x is not supported by the ADOT Lambda Go SDK");if(this.runtime.family===runtime_1().RuntimeFamily.PYTHON&&props.adotInstrumentation.execWrapper.valueOf()!==adot_layers_1().AdotLambdaExecWrapper.INSTRUMENT_HANDLER)throw new Error("Python Adot Lambda layer requires AdotLambdaExecWrapper.INSTRUMENT_HANDLER");this.addLayers(layers_1().LayerVersion.fromLayerVersionArn(this,"AdotLayer",props.adotInstrumentation.layerVersion._bind(this).arn)),this.addEnvironment("AWS_LAMBDA_EXEC_WRAPPER",props.adotInstrumentation.execWrapper)}}configureParamsAndSecretsExtension(props){if(props.paramsAndSecrets===void 0)return;const layerVersion=props.paramsAndSecrets._bind(this,this);this.addLayers(layers_1().LayerVersion.fromLayerVersionArn(this,"ParamsAndSecretsLayer",layerVersion.arn)),Object.entries(layerVersion.environmentVars).forEach(([key,value])=>this.addEnvironment(key,value.toString()))}renderLayers(){if(!(!this._layers||this._layers.length===0))return core_1().FeatureFlags.of(this).isEnabled(cx_api_1().LAMBDA_RECOGNIZE_LAYER_VERSION)&&this._layers.sort(),this._layers.map(layer=>layer.layerVersionArn)}renderEnvironment(){if(!this.environment||Object.keys(this.environment).length===0)return;const variables={},keys=this._currentVersion?Object.keys(this.environment).sort():Object.keys(this.environment);for(const key of keys)variables[key]=this.environment[key].value;return{variables}}configureVpc(props){if(props.securityGroup&&props.securityGroups)throw new Error("Only one of the function props, securityGroup or securityGroups, is allowed");const hasSecurityGroups=props.securityGroups&&props.securityGroups.length>0;if(!props.vpc){if(props.allowAllOutbound!==void 0)throw new Error("Cannot configure 'allowAllOutbound' without configuring a VPC");if(props.securityGroup)throw new Error("Cannot configure 'securityGroup' without configuring a VPC");if(hasSecurityGroups)throw new Error("Cannot configure 'securityGroups' without configuring a VPC");if(props.vpcSubnets)throw new Error("Cannot configure 'vpcSubnets' without configuring a VPC");if(props.ipv6AllowedForDualStack)throw new Error("Cannot configure 'ipv6AllowedForDualStack' without configuring a VPC");if(props.allowAllIpv6Outbound!==void 0)throw new Error("Cannot configure 'allowAllIpv6Outbound' without configuring a VPC");return}if(props.allowAllOutbound!==void 0){if(props.securityGroup)throw new Error("Configure 'allowAllOutbound' directly on the supplied SecurityGroup.");if(hasSecurityGroups)throw new Error("Configure 'allowAllOutbound' directly on the supplied SecurityGroups.")}if(props.allowAllIpv6Outbound!==void 0){if(props.securityGroup)throw new Error("Configure 'allowAllIpv6Outbound' directly on the supplied SecurityGroup.");if(hasSecurityGroups)throw new Error("Configure 'allowAllIpv6Outbound' directly on the supplied SecurityGroups.")}let securityGroups;hasSecurityGroups?securityGroups=props.securityGroups:securityGroups=[props.securityGroup||new(ec2()).SecurityGroup(this,"SecurityGroup",{vpc:props.vpc,description:"Automatic security group for Lambda Function "+core_1().Names.uniqueId(this),allowAllOutbound:props.allowAllOutbound,allowAllIpv6Outbound:props.allowAllIpv6Outbound})],this._connections=new(ec2()).Connections({securityGroups}),props.filesystem&&props.filesystem.config.connections&&this.connections.allowTo(props.filesystem.config.connections,props.filesystem.config.connections.defaultPort??ec2().Port.tcp(efs().FileSystem.DEFAULT_PORT));const ipv6AllowedForDualStack=props.ipv6AllowedForDualStack,allowPublicSubnet=props.allowPublicSubnet??!1,selectedSubnets=props.vpc.selectSubnets(props.vpcSubnets),publicSubnetIds=new Set(props.vpc.publicSubnets.map(s=>s.subnetId));for(const subnetId of selectedSubnets.subnetIds)if(publicSubnetIds.has(subnetId)&&!allowPublicSubnet)throw new Error("Lambda Functions in a public subnet can NOT access the internet. If you are aware of this limitation and would still like to place the function in a public subnet, set `allowPublicSubnet` to true");return this.node.addDependency(selectedSubnets.internetConnectivityEstablished),props.ipv6AllowedForDualStack!==void 0?{ipv6AllowedForDualStack,subnetIds:selectedSubnets.subnetIds,securityGroupIds:securityGroups.map(sg=>sg.securityGroupId)}:{subnetIds:selectedSubnets.subnetIds,securityGroupIds:securityGroups.map(sg=>sg.securityGroupId)}}configureSnapStart(props){if(props.snapStart){if(core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-lambda:snapStartRequirePublish","SnapStart only support published Lambda versions. Ignore if function already have published versions"),!props.runtime.supportsSnapStart)throw new Error(`SnapStart currently not supported by runtime ${props.runtime.name}`);if(props.filesystem)throw new Error("SnapStart is currently not supported using EFS");if(props.ephemeralStorageSize&&props.ephemeralStorageSize?.toMebibytes()>512)throw new Error("SnapStart is currently not supported using more than 512 MiB Ephemeral Storage");return props.snapStart._render()}}isQueue(deadLetterQueue){return deadLetterQueue.queueArn!==void 0}buildDeadLetterQueue(props){if(!props.deadLetterQueue&&!props.deadLetterQueueEnabled&&!props.deadLetterTopic)return;if(props.deadLetterQueue&&props.deadLetterQueueEnabled===!1)throw Error("deadLetterQueue defined but deadLetterQueueEnabled explicitly set to false");if(props.deadLetterTopic&&(props.deadLetterQueue||props.deadLetterQueueEnabled!==void 0))throw new Error("deadLetterQueue and deadLetterTopic cannot be specified together at the same time");let deadLetterQueue;return props.deadLetterTopic?(deadLetterQueue=props.deadLetterTopic,this.addToRolePolicy(new(iam()).PolicyStatement({actions:["sns:Publish"],resources:[deadLetterQueue.topicArn]}))):(deadLetterQueue=props.deadLetterQueue||new(sqs()).Queue(this,"DeadLetterQueue",{retentionPeriod:core_1().Duration.days(14)}),this.addToRolePolicy(new(iam()).PolicyStatement({actions:["sqs:SendMessage"],resources:[deadLetterQueue.queueArn]}))),deadLetterQueue}buildDeadLetterConfig(deadLetterQueue){if(deadLetterQueue)return{targetArn:this.isQueue(deadLetterQueue)?deadLetterQueue.queueArn:deadLetterQueue.topicArn}}buildTracingConfig(tracing){if(!(tracing===void 0||tracing===Tracing.DISABLED))return this.addToRolePolicy(new(iam()).PolicyStatement({actions:["xray:PutTraceSegments","xray:PutTelemetryRecords"],resources:["*"]})),{mode:tracing}}validateProfiling(props){if(!props.runtime.supportsCodeGuruProfiling)throw new Error(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`);props.environment&&(props.environment.AWS_CODEGURU_PROFILER_GROUP_NAME||props.environment.AWS_CODEGURU_PROFILER_GROUP_ARN||props.environment.AWS_CODEGURU_PROFILER_TARGET_REGION||props.environment.AWS_CODEGURU_PROFILER_ENABLED)&&core_1().Annotations.of(this).addWarning("AWS_CODEGURU_PROFILER_GROUP_NAME, AWS_CODEGURU_PROFILER_GROUP_ARN, AWS_CODEGURU_PROFILER_TARGET_REGION, and AWS_CODEGURU_PROFILER_ENABLED should not be set when profiling options enabled")}}exports.Function=Function,_a=JSII_RTTI_SYMBOL_1,Function[_a]={fqn:"aws-cdk-lib.aws_lambda.Function",version:"2.160.0"},Function._VER_PROPS={};function extractNameFromArn(arn){return core_1().Fn.select(6,core_1().Fn.split(":",arn))}function verifyCodeConfig(code,props){if([code.inlineCode,code.s3Location,code.image].filter(x=>!!x).length!==1)throw new Error('lambda.Code must specify exactly one of: "inlineCode", "s3Location", or "image"');if(!!code.image==(props.handler!==handler_1().Handler.FROM_IMAGE))throw new Error("handler must be `Handler.FROM_IMAGE` when using image asset for Lambda function");if(!!code.image==(props.runtime!==runtime_1().Runtime.FROM_IMAGE))throw new Error("runtime must be `Runtime.FROM_IMAGE` when using image asset for Lambda function");if(code.inlineCode&&!props.runtime.supportsInlineCode)throw new Error(`Inline source not allowed for ${props.runtime.name}`)}exports.verifyCodeConfig=verifyCodeConfig;function undefinedIfNoKeys(struct){return Object.values(struct).every(val=>val===void 0)?void 0:struct}class FunctionVersionUpgrade{constructor(featureFlag,enabled=!0){this.featureFlag=featureFlag,this.enabled=enabled}visit(node){if(node instanceof Function&&this.enabled===core_1().FeatureFlags.of(node).isEnabled(this.featureFlag)){const cfnFunction=node.node.defaultChild,desc=cfnFunction.description?`${cfnFunction.description} `:"";cfnFunction.addPropertyOverride("Description",`${desc}version-hash:${(0,function_hash_1().calculateFunctionHash)(node)}`)}}}exports.FunctionVersionUpgrade=FunctionVersionUpgrade,_b=JSII_RTTI_SYMBOL_1,FunctionVersionUpgrade[_b]={fqn:"aws-cdk-lib.aws_lambda.FunctionVersionUpgrade",version:"2.160.0"};
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       ^
Error: Function name can not be longer than 64 characters but has 140 characters.
    at new Function (/Users/kornherm/code/sandbox/cdkbad/node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:8408)
    at new CdkbadStack (/Users/kornherm/code/sandbox/cdkbad/lib/cdkbad-stack.ts:9:5)
    at Object.<anonymous> (/Users/kornherm/code/sandbox/cdkbad/bin/cdkbad.ts:7:1)
    at Module._compile (node:internal/modules/cjs/loader:1358:14)
    at Module.m._compile (/Users/kornherm/code/sandbox/cdkbad/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/kornherm/code/sandbox/cdkbad/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
Subprocess exited with error 1

@mrgrain
Copy link
Contributor Author

mrgrain commented Nov 30, 2024

Future error in TypeScript:

/Users/user/code/lib/cdkbad-stack.ts:9
    new lambda.Function(this, 'Function', {
    ^
ValidationError: Function name can not be longer than 64 characters but has 140 characters.
    at path [CdkbadStack/Function] in aws-cdk-lib.aws_lambda.Function

    at new CdkbadStack (/Users/user/code/lib/cdkbad-stack.ts:9:5)
    at Object.<anonymous> (/Users/user/code/bin/cdkbad.ts:7:1)
    at Module._compile (node:internal/modules/cjs/loader:1358:14)
    at Module.m._compile (/Users/user/code/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/user/code/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
    at phase4 (/Users/user/code/node_modules/ts-node/src/bin.ts:649:14)

Subprocess exited with error 1

Copy link
Contributor

@kaizencc kaizencc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example errors that you've provided are extremely helpful in seeing exactly what the outcome of this PR will be. My only consideration is whether it makes sense to put the error directly on the Construct class itself -- would benefit any other project that uses constructs as well.

@@ -1698,7 +1699,7 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett

private validateProfiling(props: FunctionProps) {
if (!props.runtime.supportsCodeGuruProfiling) {
throw new Error(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`);
throw new ValidationError(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`, this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[this question is not specific to this one instance, and is non-blocking, just for my own benefit]

when would there be a use case for the construct passed in to be anything other than this?
would it make more sense to add a method directly on Construct directly so we can instead do something like this.throwValidationError(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea and worth considering later. For aws-cdk-lib we really should have helpers available that also take into account tokens. That would give us a similar experience (albeit limited to this repo). I've considered this out-of-scope for this project.

packages/aws-cdk-lib/core/lib/errors.ts Outdated Show resolved Hide resolved
packages/aws-cdk-lib/core/lib/errors.ts Outdated Show resolved Hide resolved
* Generic, abstract error that is thrown from the users app during app construction or synth.
*/
abstract class ConstructError extends Error {
#time: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why # instead of private? just curious

Copy link
Contributor Author

@mrgrain mrgrain Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll double check but I think TypeScripts "fake" private fields will show up in the error output in an undesirable and unformattable way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed they show up like this:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this fix only in lambda.function as a POC for now and can/should eventually replace our errors all over aws-cdk?

Copy link
Contributor Author

@mrgrain mrgrain Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a soft-launch POC. I'll add a few more modules later and than towards mid January we can roll this out wholesale (a lot of grunt work).

@mrgrain mrgrain force-pushed the mrgrain/feat/improved-validation-errors-lambda branch from 980516a to f2088b9 Compare December 6, 2024 19:08
Copy link
Contributor

mergify bot commented Dec 6, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Dec 6, 2024
Copy link
Contributor

mergify bot commented Dec 6, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mrgrain
Copy link
Contributor Author

mrgrain commented Dec 7, 2024

@Mergifyio update

Copy link
Contributor

mergify bot commented Dec 7, 2024

update

☑️ Nothing to do

  • queue-position = -1 [📌 update requirement]
  • #commits-behind > 0 [📌 update requirement]
  • -closed [📌 update requirement]
  • -conflict [📌 update requirement]

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 3958233
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Copy link
Contributor

mergify bot commented Dec 7, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 2607eb3 into main Dec 7, 2024
17 checks passed
@mergify mergify bot deleted the mrgrain/feat/improved-validation-errors-lambda branch December 7, 2024 02:16
Copy link

github-actions bot commented Dec 7, 2024

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
contribution/core This is a PR that came from AWS. p2 pr-linter/exempt-integ-test The PR linter will not require integ test changes pr-linter/exempt-readme The PR linter will not require README changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants