Skip to content

Bug: decorator not returning decorated class #399

Closed
@dreamorosi

Description

@dreamorosi

Bug description

When decorating a function with @logger.injectLambdaContext() or @metrics.logMetrics() like the example below:

import { Logger } from '@aws-lambda-powertools/logger'
// OR import { Metrics } from '@aws-lambda-powertools/metrics';
import { LambdaInterface } from '@aws-lambda-powertools/commons';

const logger = new Logger({ serviceName: "my-service" } });
// OR const metrics = new Metrics({ service: "my-service", namespace: "my-namespace" });

class Lambda implements LambdaInterface {
  @logger.injectLambdaContext()
  // OR @metrics.logMetrics()
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  public handler<TEvent>(_event: TEvent, _context: unknown, _callback: unknown) {

    logger.info('Something funny!');
    logger.info('What\'s this', this);
    logger.info('(this instanceof Logger) Should be false', { actual: this instanceof Logger });
    // OR logger.info('(this instanceof Metrics) Should be false', { actual: this instanceof Metrics });
    this.myFunction();

  }

  private myFunction() {
    logger.info('Something sweet!');
  }
}

const myFunction = new Lambda();
export const handler = myFunction.handler;

The function above throws a TypeError when decorated.

image

Expected Behavior

Being able to call another method of the Lambda class using the keyword this.

Current Behavior

Throws a TypeError and fails.

Possible Solution

It seems that after decorating the Class method the value of this passes from Lambda to the Logger, this likely happens because at this point we pass this - the Logger instance - instead of target - the actual decorated class.

Same goes for Metrics but here instead.

Steps to Reproduce

  1. Deploy example above
  2. Invoke
  3. See error / observe logs

Environment

  • Powertools version used: 0.2.0-beta.19
  • Packaging format (Layers, npm): npm
  • AWS Lambda function runtime: Node.js 14.x / x86_64
  • Debugging logs: See details below
START RequestId: 6965044c-f48d-4bee-9c12-e82d8e4ecd5b Version: $LATEST
2022-01-04T18:21:14.847Z	6965044c-f48d-4bee-9c12-e82d8e4ecd5b	INFO	{"cold_start":true,"function_arn":"arn:aws:lambda:eu-west-1:123456789101:function:PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_memory_size":128,"function_name":"PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_request_id":"6965044c-f48d-4bee-9c12-e82d8e4ecd5b","level":"INFO","message":"Something funny!","service":"my-service","timestamp":"2022-01-04T18:21:14.846Z","foo":"bar"}
2022-01-04T18:21:14.904Z	6965044c-f48d-4bee-9c12-e82d8e4ecd5b	INFO	{"cold_start":true,"function_arn":"arn:aws:lambda:eu-west-1:123456789101:function:PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_memory_size":128,"function_name":"PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_request_id":"6965044c-f48d-4bee-9c12-e82d8e4ecd5b","level":"INFO","message":"What's this","service":"my-service","timestamp":"2022-01-04T18:21:14.847Z","foo":"bar","logLevelThresholds":{"DEBUG":8,"INFO":12,"WARN":16,"ERROR":20},"logsSampled":false,"persistentLogAttributes":{"foo":"bar"},"powertoolLogData":{"awsRegion":"eu-west-1","environment":"","serviceName":"my-service","xRayTraceId":"","lambdaContext":{"invokedFunctionArn":"arn:aws:lambda:eu-west-1:123456789101:function:PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","coldStart":true,"awsRequestId":"6965044c-f48d-4bee-9c12-e82d8e4ecd5b","memoryLimitInMB":128,"functionName":"PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","functionVersion":"$LATEST"}},"envVarsService":{"currentEnvironmentVariable":"ENVIRONMENT","logLevelVariable":"LOG_LEVEL","sampleRateValueVariable":"POWERTOOLS_LOGGER_SAMPLE_RATE","serviceNameVariable":"POWERTOOLS_SERVICE_NAME","awsRegionVariable":"AWS_REGION","functionNameVariable":"AWS_LAMBDA_FUNCTION_NAME","functionVersionVariable":"AWS_LAMBDA_FUNCTION_VERSION","memoryLimitInMBVariable":"AWS_LAMBDA_FUNCTION_MEMORY_SIZE","xRayTraceIdVariable":"_X_AMZN_TRACE_ID"},"logLevel":"INFO","logFormatter":{}}
2022-01-04T18:21:14.905Z	6965044c-f48d-4bee-9c12-e82d8e4ecd5b	INFO	{"cold_start":true,"function_arn":"arn:aws:lambda:eu-west-1:123456789101:function:PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_memory_size":128,"function_name":"PowerTestStack-PowerTestFunction9D6600A6-GflTt0TJkZXK","function_request_id":"6965044c-f48d-4bee-9c12-e82d8e4ecd5b","level":"INFO","message":"(this instanceof Logger) Should be false","service":"my-service","timestamp":"2022-01-04T18:21:14.905Z","foo":"bar","actual":true}
2022-01-04T18:21:14.906Z	6965044c-f48d-4bee-9c12-e82d8e4ecd5b	ERROR	Invoke Error 	{"errorType":"TypeError","errorMessage":"this.myFunction is not a function","stack":["TypeError: this.myFunction is not a function","    at Logger2.handler (/var/task/index.js:10266:10)","    at Runtime.descriptor.value [as handler] (/var/task/index.js:10002:77)","    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]}
END RequestId: 6965044c-f48d-4bee-9c12-e82d8e4ecd5b
REPORT RequestId: 6965044c-f48d-4bee-9c12-e82d8e4ecd5b	Duration: 135.41 ms	Billed Duration: 136 ms	Memory Size: 128 MB	Max Memory Used: 74 MB	Init Duration: 278.87 ms	
XRAY TraceId: 1-61d4901a-3b8339374d0393fd525d61c2	SegmentId: 223116602dbbac65	Sampled: true

Related issues, RFCs

N/A

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcompletedThis item is complete and has been merged/shippedloggerThis item relates to the Logger UtilitymetricsThis item relates to the Metrics UtilitytracerThis item relates to the Tracer Utility

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions