-
Notifications
You must be signed in to change notification settings - Fork 156
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
AWS Lambda Node 8.10 Runtime Support #27
Comments
You can find more details in this thread: #12 around async support. Please let me know if you have additional questions. Could you provide the server side stack trace on the 5xx? |
There's actually no server-side stack trace. The lambda code executes correctly, but passes a promise instead of a response object back to API Gateway which doesn't know how to handle it. The API Gateway logs (once you figure out how to enable them) says:
|
We will do some testing around the new Lambda node runtime and update the thread soon. One thing to confirm is that for the 502 you simply did |
The three examples I posted are the only code I wrote. I'm using |
Thank you for the information. We will also do some testing around raw Lambda function to start with. |
If you guys need simple reproducible steps, please refer #29. |
Another report #29 for the same issue. I successfully reproduced the issue using the hello world example Lambda provides. |
It looks like the problem happens on CLS which the SDK has direct dependency on. Here is a repro: require('continuation-local-storage');
exports.handler = async (event) => {
return 'Hello from Lambda!';
}; Test event result:
The working //require('continuation-local-storage');
exports.handler = async (event) => {
return 'Hello from Lambda!';
}; Test event result:
So it looks like the new async handler provided by Lambda node 8.10 runtime will have issues if your application code has indirect dependency on CLS. We will contact Lambda team for more insights. Ideally simply importing CLS should not affect what the async handler returns. |
after more investigation, it seems depending package more specific re-pro code: module.exports.foo = async (event) =>
require('async-listener');
return 3;
} The |
Okay. here some code goes: so it causes the issue. interesting thing is: 'use strict';
// below function results `null` anyway
module.exports.hello = async (event) => {
const p = new Promise((resolve) => setTimeout(resolve, 1000 * 10));
// Backup original promise
const originalPromise = global.Promise;
require('async-listener');
// Now promise is patched by async-listener
console.log('Promise is same before?', global.Promise === originalPromise); // prints false, funny!
// Promise detection is broken also:
const isPromise = Promise.resolve(p) === p; // surprise!
console.log('isPromise?', isPromise); // false. wait, what????? we expected true!
return 3;
}; 'use strict';
// surprise! we can get 3!
module.exports.hello = async (event) => {
// Backup original promise
const originalPromise = global.Promise;
require('async-listener');
// Now promise is patched by async-listener
// Simply restore original Promise
global.Promise = originalPromise;
return 3;
}; |
Okay. Finally i found the reason why lambda returns null. Here goes:
According to Line 287~290 (end of so for now below two code will have same effect: 'use strict';
module.exports.hello = async (event) => {
require('async-listener'); // patches global.Promise object
return 3;
}; 'use strict';
const BbPromise = require('bluebird');
module.exports.hello = (event) => BbPromise.resolve(3); // returns instance of bluebird promise |
so to Lambda team: Please use if (response && typeof response.then === 'function') { // given response is promise-like object
response.then(context.succeed);
response.catch(context.fail);
} Please note Node.js project has thenable test suite, so if you need some tests please refer here: |
Hi Mooyoul, Thank you for the detailed deep dive. We have reached out to the Lambda team and will be following up on this ASAP. Sorry for the trouble, |
Hello @awssandra , do you have a timeline for those changes? |
We are continuing to prioritize this fix with the Lambda team. Please stay tuned for updates, we'll update this thread accordingly when we have more news. Sorry for the trouble, |
I've also experienced this issue when returning a Bluebird promise in AWS lambda using the node 8.10 runtime, thanks for the explanation @mooyoul 👍 |
We are facing this problem too! |
This can be fixed from xray sdk also if you just find an alternative for CLS. i mean whole problem is that CLS override global Promise with bluebird |
We have a path to resolution with Lambda and are hoping for fixed to be release soon. We are aware of the unfortunately long time this has taken, and appreciate your continued patience as we work with Lambda to fix this correctly. We plan to work more closely with Lambda in future releases so that we can identify and fix incompatibilities/issues early. Sorry for the trouble, |
Any update on this issue? |
@awssandra can we get an ETA on this, as this is a critical bug I feel like and prevents people from fully using xray. |
so for now, there's only one option that we can do: For example: const BbPromise = require('bluebird');
module.exports.foo = wrap(async (event) => {
return 3;
});
function wrap(handler) {
return (event, context, callback) => {
BbPromise.resolve(handler(event, context)).asCallback(callback);
};
} |
Will this ever get fixed? A lot of people are using node 8 runtime and don't want to use callbacks. |
I was hit by simply returning Looks exactly like what @mooyoul has described in detail. Is there a ticket or smth. on this issue on some public Lambda team tracker? |
Hi everyone, We're moving on this with the Lambda team as we speak, thank you for all of your patience. We'll update as soon as we can. |
Hi, any update? Edit: nvm, in the meantime I'll just use @mooyoul callbackify trick with native Promises const util = require('util');
async function hello(event, context) {
return { event, context, message: 'Hello world!' };
}
exports.handler = util.callbackify(hello); |
Hi everyone, Lambda has finished rolling out the fix. Please let us know of any further issues. Thank you again for all your patience. |
Just tested this in Here's snippet I used to test 'use strict';
const bbPromise = global.Promise = require('bluebird');
module.exports.handler = async (event, context) => {
return new bbPromise((resolve, reject)=>{
let response = {
statusCode: 200,
body: JSON.stringify({
message: 'If you see this, you returned bluebird promise from async function upstream to Lambda 8.10 Runtime!',
}),
};
setTimeout(()=>{
resolve(response);
}, 3000);
});
}; |
How to test? I don't see any new version.. |
The Lambda 8.10 runtime was updated from Lambda's end. All existing Lambda 8.10 functions have been updated behind the scenes, and should no longer break with the existing X-Ray SDK. |
It looks like the xray sdk instruments the handler with the assumption that the handler will follow the callback pattern required in node 4 and 6. With node 8,
async
functions are available (and encouraged in the node 8 on lambda blog post), but including the sdk without wrapping the async handler fails.Working:
Broken:
Workaround:
The text was updated successfully, but these errors were encountered: