-
Notifications
You must be signed in to change notification settings - Fork 340
/
synchronous.js
86 lines (70 loc) · 2.54 KB
/
synchronous.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// @ts-check
const { Buffer } = require('buffer')
const { NETLIFYDEVERR } = require('../../utils')
const renderErrorTemplate = require('../render-error-remplate')
const { detectAwsSdkError } = require('./utils')
const addHeaders = (headers, response) => {
if (!headers) {
return
}
Object.entries(headers).forEach(([key, value]) => {
response.setHeader(key, value)
})
}
const handleSynchronousFunction = function (err, result, request, response) {
if (err) {
return handleErr(err, request, response)
}
const { error } = validateLambdaResponse(result)
if (error) {
console.log(`${NETLIFYDEVERR} ${error}`)
return handleErr(error, request, response)
}
response.statusCode = result.statusCode
addHeaders(result.headers, response)
addHeaders(result.multiValueHeaders, response)
if (result.body) {
response.write(result.isBase64Encoded ? Buffer.from(result.body, 'base64') : result.body)
}
response.end()
}
const formatLambdaLocalError = (err, acceptsHtml) =>
acceptsHtml
? JSON.stringify({
errorType: err.errorType,
errorMessage: err.errorMessage,
trace: err.stackTrace,
})
: `${err.errorType}: ${err.errorMessage}\n ${err.stackTrace.join('\n ')}`
const processRenderedResponse = async (err, request) => {
const acceptsHtml = request.headers && request.headers.accept && request.headers.accept.includes('text/html')
const errorString = typeof err === 'string' ? err : formatLambdaLocalError(err, acceptsHtml)
return acceptsHtml
? await renderErrorTemplate(errorString, './templates/function-error.html', 'function')
: errorString
}
const handleErr = async (err, request, response) => {
detectAwsSdkError({ err })
response.statusCode = 500
response.end(await processRenderedResponse(err, request))
}
const validateLambdaResponse = (lambdaResponse) => {
if (lambdaResponse === undefined) {
return { error: 'lambda response was undefined. check your function code again' }
}
if (lambdaResponse === null) {
return {
error: 'no lambda response. check your function code again. make sure to return a promise or use the callback.',
}
}
if (!Number(lambdaResponse.statusCode)) {
return {
error: `Your function response must have a numerical statusCode. You gave: $ ${lambdaResponse.statusCode}`,
}
}
if (lambdaResponse.body && typeof lambdaResponse.body !== 'string') {
return { error: `Your function response must have a string body. You gave: ${lambdaResponse.body}` }
}
return {}
}
module.exports = { handleSynchronousFunction }