honeybadger-js: Unable to get an error thrown from inside the handler after wrapping it in lambdaHandler
What are the steps to reproduce this issue?
- Create an APIGateway handler method for AWS lambda
- Throw an error inside the handler.
- Add a test to execute the handler to throw an error. The error never gets thrown.
I have my main handler as defined below:
import { APIGatewayProxyHandler } from 'aws-lambda';
import Honeybadger from '@honeybadger-io/js';
const handler: APIGatewayProxyHandler = async(event, context) => {
//performs some logic or throw an error
try { // blah }
catch(err) { throw new Error('Some Error); }
}
export default Honeybadger.lambdaHandler(handler);
In my tests I import this handler and want the test to fail
import handler form '../index.ts';
describe('Handler', () => {
test('Error is handled', async () => {
try {
// valid event and context are manually added fixtures
await handler(validEvent, context);
throw new Error('handler should throw an error');
} catch(err) {
expect((<Error>e).message).toBe('Some Error');
}
});
});
What happens?
There are two things that are happening wrong.
- The handler code doesn’t get executed synchronously during the tests. Any
console.log
that I add to the handler show up after the test has ended. I am usingJest
for testing. - The handler never throws the error as is being expected due to it being executed in an async manner.
What were you expecting to happen?
I was expecting that my handlers and tests keep on working as they were before I started wrapping them in lambdaHandler
.
Any logs, error output, etc?
As stated above, the code works in an async manner. I see logs after the test has ended. The await
doesn’t seem to work.
Any other comments?
It looks like the wrapper is not using Promise
. It expects a callback to be passed to it to which is passes the error
in case and error is produced. Please correct me if my understanding is wrong.
What versions are you using?
Operating System: Mac OS Big Sur 11.4 (20F71) …
Package Version: "@honeybadger-io/js": "^3.2.5"
…
Browser Version: Node 14, Typescript, “aws-lambda”: “^1.0.6” …
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (11 by maintainers)
Commits related to this issue
- #648 Callback not called on lambda handler if notify returns false (#650) * call callback when notify() returns false * add tests * CHANGELOG.md * fix tests * remove references to ignoreP... — committed to honeybadger-io/honeybadger-js by subzero10 3 years ago
- #648 Callback not called on lambda handler if handler is async (#652) * make sure to call async handler callback * add CHANGELOG.md * fix comments — committed to honeybadger-io/honeybadger-js by subzero10 3 years ago
I’m just glad I was able to help! Please don’t hesitate to contact us again if you have any questions/suggestions/issues in the future!
Awesome, you will not regret it! And yes, we will release an update asap.
There is some discussion on refactoring our code to support promises, but I would direct this question to @joshuap . However, you could wrap the handler to a promise and call async/await yourself until we implement this officially:
Thanks @subzero10. I think we can start integration of
honeybadger
on our end. I am assuming this would be released as apatch
update and the package will get updated next time we to a freshnpm i
.As an additional question. Is there a plan to move this to a Promise based mechanism to that we can simply use
async/await
when calling thelambdaHandler
instead of passing in a callback deliberately?I understand.
reportData
is actually one of the preconditions I mentioned above. That’s why it behaves the same as not supplying anapiKey
.You are correct, my PR should call the callback even when
reportData
isfalse
.Hey @tweaktastic, After inspecting more thoroughly the code, I noticed that we actually support async lambda handlers! 😌 The code is not super readable because it has to support both async and non-async and that’s why I missed it on my first read.
Honeybadger.lambdaHandler
takes an async (or a callback-based handler) and returns a callback-based handler. Your tests are failing because you are calling Honybadger’s lambda handler with async/await. You can try calling it with a callback-based approach:Let me know if that works for you so I can close the ticket. Thanks!
cc @joshuap Please ignore my comment above on creating a ticket.
Hey @tweaktastic, I’m glad to see that you are finally getting errors reported on Honeybadger.
Have you looked into the
beforeNotify
handler? That could help achieve what you want. I’m not 100% sure though, since I haven’t read your source code. But it may be possible if you register some callbacks to be called in thebeforeNotify
handler. The callback is called with aNotice
object with acontext
property that you can use to add custom data.We may be able to add an option for that to happen automatically or see if we can come up with a workaround. Can you clarify what you mean with the phrase
report an alarm
? Personally, I think error codes similar to400
,401
,403
and429
should not be reported to your error monitoring tool but to your logging service (i.e. Cloudwatch), but I will look into that nevertheless.Can you please confirm that the increased execution times refer to the time for the client to receive the response and not the lambda function execution time? Because it would make sense for the lambda function to have increased execution time (since it has to wait for the http request to complete), but ideally it should happen after the response is sent to the client.
@tweaktastic I’m glad that it works on your side also.
The patch should be pretty soon, but I think @joshuap is better suited to answer that.
@tweaktastic I’m really sorry you are facing issues with our package! Can you please try the fix in the branch of this PR?
Thank you for not giving up!
cc @joshuap
Hi @subzero10. Sorry to bother you again. But the callbacks are not working in the manner they should.
In one of our handlers we want to return a some data (
statusCode
,body
). It looks like when wrap our handlers inlambdaHandler
, the handlers keep on executing forever and never exit, thus never returning any response. You can check the update code in the repo. https://github.com/tweaktastic/honeybadger-testing The tests in which an error is thrown passes correctly, while the one in which we are waiting for a response from the handler timesout.On checking this handler with
serverless framework
on my dev env I was able to see that the request keeps in execution without ever getting a response back.Thanks for all your help @subzero10. I really appreciate your feedback and your quick response regarding this. We will wrap the handler to return the Promise as you have mentioned. Looking forward to use
Honeybadger
alerting.