AWS Lambda报错‘Process exited before completing request’排查求助
Hey there, let's break down why your Lambda is throwing that frustrating error and fix it step by step. The core issue here is how you're handling asynchronous code—let's dive in:
1. The Big Problem: Asynchronous Timing
The request function runs asynchronously, meaning your callback gets called before the web scrape finishes. Lambda terminates the process as soon as callback is invoked, so the request callback never gets a chance to complete. That's exactly why you see "Process exited before completing request".
You need to move your callback inside the request callback, so it only runs after the scrape and string building are done.
2. Other Issues to Fix
- Misusing
context.done(): This is an older Lambda API, and you should use thecallbackparameter instead to pass errors. If the request fails, callcallback(err)to let Lambda know something went wrong. - Incorrect
stringbuilderusage: You're callingstringbuilder.appenddirectly without creating an instance of the stringbuilder. Plus, for simple string concatenation like this, you could even use a regular array andjoin()to avoid extra dependencies entirely. - Possible selector mistake:
$('menu-item-title')looks for a<menu-item-title>HTML tag, which is unlikely. You probably meant a class selector (.menu-item-title) or ID selector (#menu-item-title)—double-check the actual HTML structure of the page you're scraping.
Fixed Code Example
Here's the revised code with all these fixes applied:
'use strict'; var cheerio = require('cheerio'); var request = require('request'); var AWS = require('aws-sdk'); var moment = require('moment'); exports.handler = function (event, context, callback) { var diningHall = event.currentIntent.slots.diningHallName; var webpage = event.webpage; // Ensure this URL is correctly passed from Lex // Wrap all logic inside the request callback to ensure timing is correct request(webpage, function (err, response, body) { if (err) { // Pass errors to Lambda for proper logging and handling return callback(err); } var $ = cheerio.load(body); var menus = []; // Fix the selector here—use .menu-item-title if it's a class, # if it's an ID $('.menu-item-title').each(function (i, elem) { menus.push($(this).text().trim()); // Trim extra whitespace for cleaner output }); // Build the final message with a fallback if no items are found var menuList = menus.length > 0 ? menus.join("\n") : "No menu items found for this dining hall"; var messageContent = `Here is what is being offered in the ${diningHall}\n${menuList}`; // Only call callback once all processing is complete callback(null, { "dialogAction": { "type": "Close", "fulfillmentState": "Fulfilled", "message": { "contentType": "PlainText", "content": messageContent } } }); }); };
Quick Additional Tips
- If you still want to use
stringbuilder, you'll need to initialize it first withvar sb = new stringbuilder();, then callsb.append(...)for each item, and finally get the full string withsb.toString()(check the package docs for exact usage). - Test your scrape logic locally first (using
nodeor tools likeserverless invoke local) to verify it works before deploying to Lambda—this saves you time debugging in the cloud. - Double-check that
event.webpageis being correctly passed from your Lex bot to Lambda—misconfigured slots can lead to empty or invalid URLs.
内容的提问来源于stack exchange,提问作者optimist132

