Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit f3e7620

Browse files
author
sw-yx
committed
fix the async and callback combo issue and the reload issue
1 parent 5160b2a commit f3e7620

File tree

1 file changed

+69
-50
lines changed

1 file changed

+69
-50
lines changed

src/utils/serve-functions.js

+69-50
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const path = require("path");
77
const getPort = require("get-port");
88
const chokidar = require("chokidar");
99
const jwtDecode = require("jwt-decode");
10-
// const chalk = require("chalk");
10+
const chalk = require("chalk");
1111
const {
1212
NETLIFYDEVLOG,
1313
// NETLIFYDEVWARN,
@@ -27,52 +27,10 @@ function handleErr(err, response) {
2727
console.log(`${NETLIFYDEVERR} Error during invocation: `, err); // eslint-disable-line no-console
2828
}
2929

30-
function createCallback(response) {
31-
return function(err, lambdaResponse) {
32-
if (err) {
33-
return handleErr(err, response);
34-
}
35-
if (lambdaResponse === undefined) {
36-
return handleErr(
37-
"lambda response was undefined. check your function code again.",
38-
response
39-
);
40-
}
41-
if (!Number(lambdaResponse.statusCode)) {
42-
console.log(
43-
`${NETLIFYDEVERR} Your function response must have a numerical statusCode. You gave: $`,
44-
lambdaResponse.statusCode
45-
);
46-
return handleErr("Incorrect function response statusCode", response);
47-
}
48-
if (typeof lambdaResponse.body !== "string") {
49-
console.log(
50-
`${NETLIFYDEVERR} Your function response must have a string body. You gave:`,
51-
lambdaResponse.body
52-
);
53-
return handleErr("Incorrect function response body", response);
54-
}
55-
56-
response.statusCode = lambdaResponse.statusCode;
57-
// eslint-disable-line guard-for-in
58-
for (const key in lambdaResponse.headers) {
59-
response.setHeader(key, lambdaResponse.headers[key]);
60-
}
61-
console.log({ lambdaResponse });
62-
response.write(
63-
lambdaResponse.isBase64Encoded
64-
? Buffer.from(lambdaResponse.body, "base64")
65-
: lambdaResponse.body
66-
);
67-
response.end();
68-
};
69-
}
70-
7130
// function getHandlerPath(functionPath) {
7231
// if (functionPath.match(/\.js$/)) {
7332
// return functionPath;
7433
// }
75-
7634
// return path.join(functionPath, `${path.basename(functionPath)}.js`);
7735
// }
7836

@@ -122,7 +80,12 @@ function createHandler(dir) {
12280

12381
Object.keys(functions).forEach(name => {
12482
const fn = functions[name];
125-
const clearCache = () => {
83+
const clearCache = action => () => {
84+
console.log(
85+
`${NETLIFYDEVLOG} function ${chalk.yellow(
86+
name
87+
)} ${action}, reloading...`
88+
); // eslint-disable-line no-console
12689
const before = module.paths;
12790
module.paths = [fn.moduleDir];
12891
delete require.cache[require.resolve(fn.functionPath)];
@@ -136,9 +99,9 @@ function createHandler(dir) {
13699
ignored: /node_modules/
137100
});
138101
fn.watcher
139-
.on("add", clearCache)
140-
.on("change", clearCache)
141-
.on("unlink", clearCache);
102+
.on("add", clearCache("added"))
103+
.on("change", clearCache("modified"))
104+
.on("unlink", clearCache("deleted"));
142105
});
143106

144107
return function(request, response) {
@@ -177,7 +140,7 @@ function createHandler(dir) {
177140
if (body instanceof Buffer) {
178141
isBase64Encoded = true;
179142
body = body.toString("base64");
180-
} else if(typeof(body) === "string") {
143+
} else if (typeof body === "string") {
181144
// body is already processed as string
182145
} else {
183146
body = "";
@@ -192,13 +155,64 @@ function createHandler(dir) {
192155
isBase64Encoded: isBase64Encoded
193156
};
194157

158+
let callbackWasCalled = false;
195159
const callback = createCallback(response);
196160
const promise = handler.handler(
197161
lambdaRequest,
198162
{ clientContext: buildClientContext(request.headers) || {} },
199163
callback
200164
);
201-
promiseCallback(promise, callback);
165+
/** guard against using BOTH async and callback */
166+
if (callbackWasCalled && promise && typeof promise.then === "function") {
167+
throw new Error(
168+
"Error: your function seems to be using both a callback and returning a promise (aka async function). This is invalid, pick one. (Hint: async!)"
169+
);
170+
} else {
171+
// it is definitely an async function with no callback called, good.
172+
promiseCallback(promise, callback);
173+
}
174+
175+
/** need to keep createCallback in scope so we can know if cb was called AND handler is async */
176+
function createCallback(response) {
177+
return function(err, lambdaResponse) {
178+
callbackWasCalled = true;
179+
if (err) {
180+
return handleErr(err, response);
181+
}
182+
if (lambdaResponse === undefined) {
183+
return handleErr(
184+
"lambda response was undefined. check your function code again.",
185+
response
186+
);
187+
}
188+
if (!Number(lambdaResponse.statusCode)) {
189+
console.log(
190+
`${NETLIFYDEVERR} Your function response must have a numerical statusCode. You gave: $`,
191+
lambdaResponse.statusCode
192+
);
193+
return handleErr("Incorrect function response statusCode", response);
194+
}
195+
if (typeof lambdaResponse.body !== "string") {
196+
console.log(
197+
`${NETLIFYDEVERR} Your function response must have a string body. You gave:`,
198+
lambdaResponse.body
199+
);
200+
return handleErr("Incorrect function response body", response);
201+
}
202+
203+
response.statusCode = lambdaResponse.statusCode;
204+
// eslint-disable-line guard-for-in
205+
for (const key in lambdaResponse.headers) {
206+
response.setHeader(key, lambdaResponse.headers[key]);
207+
}
208+
response.write(
209+
lambdaResponse.isBase64Encoded
210+
? Buffer.from(lambdaResponse.body, "base64")
211+
: lambdaResponse.body
212+
);
213+
response.end();
214+
};
215+
}
202216
};
203217
}
204218

@@ -225,7 +239,12 @@ async function serveFunctions(settings) {
225239
port: assignLoudly(settings.port, defaultPort)
226240
});
227241

228-
app.use(bodyParser.text({ limit: "6mb", type: ["text/*", "application/json", "multipart/form-data"] }));
242+
app.use(
243+
bodyParser.text({
244+
limit: "6mb",
245+
type: ["text/*", "application/json", "multipart/form-data"]
246+
})
247+
);
229248
app.use(bodyParser.raw({ limit: "6mb", type: "*/*" }));
230249
app.use(
231250
expressLogging(console, {

0 commit comments

Comments
 (0)