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

[SVLS-4699] Detect exceptions raised outside of the handler #533

Merged

Conversation

TalUsvyatsky
Copy link
Contributor

@TalUsvyatsky TalUsvyatsky commented May 2, 2024

What does this PR do?

This PR adds telemetry for exceptions that occur outside of the handler function.

When an exception occurs outside of the handler function:

  1. aws.lambda.enhanced.errors is emitted
  2. A trace with an error span is created

Motivation

Testing Guidelines

  1. Created a handler file like this for testing "cjs" handler:
  throw new TypeError("im a type error")
  exports.handler = function async (event) {
    const response = {
      statusCode: 200,
      body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
  };

and one like this for testing "mjs" handler:

  throw new TypeError("im a type error")
  export const handler = async (event) => {
    const response = {
      statusCode: 200,
      body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
  };
  1. Deployed my function using each handler and invoked it
  2. Saw traces with an error span from the call (example trace)
  3. Saw aws.lambda.enhanced.errors emitted (graph)
  4. Traces appear in serverless detail page invocation table (link to search for function)
  5. Issues appear in error tracking and are informative

Additional Notes

Types of Changes

  • Bug fix
  • New feature
  • Breaking change
  • Misc (docs, refactoring, dependency upgrade, etc.)

Check all that apply

  • This PR's description is comprehensive
  • This PR contains breaking changes that are documented in the description
  • This PR introduces new APIs or parameters that are documented and unlikely to change in the foreseeable future
  • This PR impacts documentation, and it has been updated (or a ticket has been logged)
  • This PR's changes are covered by the automated tests
  • This PR collects user input/sensitive content into Datadog
  • This PR passes the integration tests (ask a Datadog member to run the tests)

@TalUsvyatsky TalUsvyatsky force-pushed the tal.usvyatsky/capture-exceptions-outside-of-handler branch 4 times, most recently from c96415d to a0c2e24 Compare May 2, 2024 17:59
@codecov-commenter
Copy link

codecov-commenter commented May 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.10%. Comparing base (78c1900) to head (249712e).
Report is 8 commits behind head on main.

❗ Current head 249712e differs from pull request most recent head 75ae1c8. Consider uploading reports for the commit 75ae1c8 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #533      +/-   ##
==========================================
+ Coverage   81.75%   82.10%   +0.35%     
==========================================
  Files          54       56       +2     
  Lines        2209     2286      +77     
  Branches      515      529      +14     
==========================================
+ Hits         1806     1877      +71     
- Misses        337      344       +7     
+ Partials       66       65       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@TalUsvyatsky TalUsvyatsky force-pushed the tal.usvyatsky/capture-exceptions-outside-of-handler branch 7 times, most recently from ef5ba7e to e0259a0 Compare May 6, 2024 14:42
@TalUsvyatsky TalUsvyatsky force-pushed the tal.usvyatsky/capture-exceptions-outside-of-handler branch from 375112c to 02e9ae7 Compare May 7, 2024 15:13
@TalUsvyatsky TalUsvyatsky force-pushed the tal.usvyatsky/capture-exceptions-outside-of-handler branch from 5a9d85c to 050662c Compare May 7, 2024 17:24
@TalUsvyatsky TalUsvyatsky marked this pull request as ready for review May 7, 2024 17:42
@TalUsvyatsky TalUsvyatsky requested a review from a team as a code owner May 7, 2024 17:42
src/handler.cjs Outdated
try {
exports.handler = datadog(loadSync(taskRootEnv, handlerEnv), { traceExtractor });
} catch (error) {
emitTelemetryOnErrorOutsideHandler(error, handlerEnv, Date.now());
Copy link
Contributor

@joeyzhao2018 joeyzhao2018 May 7, 2024

Choose a reason for hiding this comment

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

I might be wrong but is this fire and forget way of invoking the async method? I'm just wondering if we need to add a.catch(error => { // something like logDebug(error) });

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks! yes I think you're right, added

src/handler.mjs Outdated
@@ -26,4 +33,12 @@ if (extractorEnv) {
}
}

export const handler = datadog(await load(taskRootEnv, handlerEnv), { traceExtractor });
let wrapped_handler;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: use camel case wrappedHandler

if (context.invokedFunctionArn) {
arnTags = parseTagsFromARN(context.invokedFunctionArn, context.functionVersion);
}
tags = [...arnTags, `memorysize:${context.memoryLimitInMB}`];
Copy link
Contributor

Choose a reason for hiding this comment

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

Does js have an append-like function? so we don't have to do the extra allocation.

@TalUsvyatsky TalUsvyatsky force-pushed the tal.usvyatsky/capture-exceptions-outside-of-handler branch from c04d253 to f14e402 Compare May 7, 2024 19:02
Copy link
Contributor

@duncanista duncanista left a comment

Choose a reason for hiding this comment

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

Left some comments.

src/index.ts Outdated
Comment on lines 448 to 453
const metricsListener = new MetricsListener(new KMSService(), config);
await metricsListener.onStartInvocation(undefined);
if (config.enhancedMetrics) {
incrementErrorsMetric(metricsListener);
}
await metricsListener.onCompleteInvocation();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't we just lazy load everything inside of the condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! Updated

src/metrics/enhanced-metrics.ts Show resolved Hide resolved
@TalUsvyatsky TalUsvyatsky requested a review from duncanista May 8, 2024 19:26
@TalUsvyatsky TalUsvyatsky merged commit 6c0447d into main May 9, 2024
25 checks passed
@TalUsvyatsky TalUsvyatsky deleted the tal.usvyatsky/capture-exceptions-outside-of-handler branch May 9, 2024 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants