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

feat: #220 AWS Lambda Handler #244

Closed
wants to merge 33 commits into from
Closed

feat: #220 AWS Lambda Handler #244

wants to merge 33 commits into from

Conversation

miquelbeltran
Copy link
Contributor

@miquelbeltran miquelbeltran commented Jun 4, 2024

feat: AWS Lambda Handler

Description 📝

Usage is as follows:

// Setup Raygun client as before
const client = new raygun.Client().init({ apiKey: process.env.RAYGUN });

// Wrap the AWS Lambda function with the `awsHandler()` function
exports.handler = awsHandler({ client }, async function (event, context) {
  // Your AWS Lambda function code
});

Any errors occurring in your AWS Lambda function will be automatically captured by Raygun.

Also, any breadcrumbs will be automatically scoped to the function session.

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Updates

  • Created sub-package @raygun.io/aws-lambda in aws-lambda folder. Package name follows the organization scope format: https://docs.npmjs.com/about-organization-scopes-and-packages like we do with the @raygun.io/webpack-plugin.
  • Setup eslint, prettier, tests for new project.
  • Created raygun.aws.ts with new AWS Handler code.
  • Created documentation in README.md
  • Created tests in aws-lambda/test/raygun_aws_test.js
  • Created example in examples/aws-lambda-sample including instructions and prepare.sh script.
  • Created GitHub CI job for aws-lambda package in .github/workflows/aws-lambda.yml.

TODO:

  • Release base raygun package with required breadcrumbs function change.
  • Update dependencies in package.json to point to new raygun release.
  • Remove path reference in .github/workflows/aws-lambda.yml

Test plan 🧪

  • Created example and run on AWS Lambda
  • Created unit tests

Author to check 👓

  • Project and all contained modules builds successfully
  • Self-/dev-tested
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

Reviewer to check ✔️

  • Project and all contained modules builds successfully
  • Change has been dev-/reviewer-tested, where possible
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

@miquelbeltran miquelbeltran marked this pull request as ready for review June 6, 2024 09:04
},
"dependencies": {
"@types/aws-lambda": "^8.10.138",
"raygun": "file:../"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: Change this file reference to ^1.1.0 when 1.1.0 is released.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copied from root tsconfig.json file

Copy link

Choose a reason for hiding this comment

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

Will typescript automatically search up the tree for config? Do we want this to be a second root?

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 question, I will see if it is the case.

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 resolved this using "extends": "../tsconfig.json", plus a couple of changes

@@ -25,6 +25,7 @@ export default tseslint.config(
"process": false,
"require": false,
"setTimeout": false,
"exports": false,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ignore error in exports.handler from the aws-lambda-sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To better read this file and see the screenshots, tap on ". . ." and select "View file"

@miquelbeltran miquelbeltran requested review from a team, nikz, TheRealAgentK and sumitramanga and removed request for a team June 6, 2024 09:10
Copy link

@nikz nikz left a comment

Choose a reason for hiding this comment

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

Some really small nits or questions from my testing, but nothing that should stop you shipping 🚢

examples/aws-lambda-sample/README.md Outdated Show resolved Hide resolved

![Screenshot from 2024-06-06 10-33-11](https://github.com/MindscapeHQ/raygun4node/assets/2494376/762e07b9-e456-4dc2-b9b9-65228ef7f09c)

You should see execution results similar to these:
Copy link

Choose a reason for hiding this comment

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

CleanShot 2024-06-07 at 13 45 37@2x

I see something like this, I'm guessing that's expected? I don't see "from callback!" in there so maybe I'm doing something dumb :)

index.js includes the message I see, so perhaps this file just needs updating?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks correct to me. The awsHandler rethrows the error and we can seee the "successfully sent message".

I don't see "from callback!" in there

I forgot to update the pasted logs when I changed the example code, I will update that.

But looks like the example run as expected.

Copy link

Choose a reason for hiding this comment

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

Will typescript automatically search up the tree for config? Do we want this to be a second root?

@paul-uz
Copy link

paul-uz commented Jun 7, 2024

We already have an internal SDK we use to construct our Lambda Handlers, using abstract classes and various other helper classes. Something like below:

class Handler exports AbstractHandler {
    main = async () => {
        // code here in a try/catch
    }
}
const handler = new Handler({
    // maybe some options set
})
export const main = handler.main.bind(handler);

How would this awsHandler work with our setup?

also, whats the ETA on getting this released, as I'm struggling to get WinstonJS and Raygun playing nicely together, so this would be a god send.

@miquelbeltran
Copy link
Contributor Author

@paul-uz since the awsHandler() we are implementing will accept any kind of generic Handler from AWS as input, I believe something like this in your index.js:

// client is the Raygun Client instance
exports.handler = awsHandler({ client }, handler);

The advantage of using our awsHandler is that it will scope breadcrumbs and report errors automatically.

ETA still hard to say, we are considering moving the @raygun.io/aws-lambda package to a new GitHub repo, plus there are some other internal open questions

@paul-uz
Copy link

paul-uz commented Jun 7, 2024

@miquelbeltran looking at your example code

exports.handler = awsHandler({ client }, async function (event, context) {
  // Your AWS Lambda function code
});

It looks to me that the 2nd param is equivalent to my main method, as thats the method in the class that takes the event and context. Just trying to understand how this new raygun handler would slot into our process.

Also, in your example, you use throw "It's an AWS error!"; rather than throw new Error("It's an AWS error!"); - why is that? Can raygun support Error()'s?

@miquelbeltran
Copy link
Contributor Author

It looks to me that the 2nd param is equivalent to my main method, as thats the method in the class that takes the event and context.

That would be the idea, yes. The method accepts any Handler as defined by AWS, which can be either async function (event, context) {} or function (event, context, callback) {}. I need to check if handlers like async function (event) are supported too. The goal is that the method accepts whatever users are already using as function handlers currently.

Also, in your example, you use throw "It's an AWS error!"; rather than throw new Error("It's an AWS error!"); - why is that? Can raygun support Error()'s?

Yes, just like the send() method accepts Error or string. Thanks for asking, I will ensure we mention this in the docs.

@paul-uz
Copy link

paul-uz commented Jun 7, 2024

It looks to me that the 2nd param is equivalent to my main method, as thats the method in the class that takes the event and context.

That would be the idea, yes. The method accepts any Handler as defined by AWS, which can be either async function (event, context) {} or function (event, context, callback) {}. I need to check if handlers like async function (event) are supported too. The goal is that the method accepts whatever users are already using as function handlers currently.

Also, in your example, you use throw "It's an AWS error!"; rather than throw new Error("It's an AWS error!"); - why is that? Can raygun support Error()'s?

Yes, just like the send() method accepts Error or string. Thanks for asking, I will ensure we mention this in the docs.

Hmm, ideally, I'd like to be able to pass our custom Handler class (which contains the main "handler" method) or have some way of including this new awsHandler in my class?

I'm wondering if I could do something like this?

const client = new raygun.Client().init({ apiKey: process.env.RAYGUN });

class Handler extends AbstractHandler {
    main = async (event) {
        console.log(event)
        ...
    }
}

const handler = new Handler();
export const main = awsHandler({ client }, handler.main(event));`

@miquelbeltran
Copy link
Contributor Author

I believe it will be like:

export const main = awsHandler({ client }, handler.main);`

I think you should be able to try it already. You can clone this repo/branch and install the package as reference. Let me know how it goes!

@miquelbeltran
Copy link
Contributor Author

This PR got moved to the repo https://github.com/MindscapeHQ/raygun4node-aws-lambda

TODO List before version 0.0.1: MindscapeHQ/raygun4node-aws-lambda#1

@miquelbeltran miquelbeltran deleted the aws-lambda branch December 3, 2024 07:19
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.

Example: AWS Lambda Functions example (or similar cloud provider)
3 participants