wake-up-neo.net

AWS-Lambda-API-Gateway-Fehler "Falsch geformte Lambda-Proxy-Antwort"

Ich versuche, ein Hallo Weltbeispiel mit AWS Lambda aufzubauen und es über ein API-Gateway zu bedienen. Ich klickte auf "Create a Lambda Function", um das API-Gateway einzurichten, und wählte die Option Leere Funktion. Ich habe die Lambda-Funktion in AWS Gateway - Erste Schritte hinzugefügt: 

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};

Das Problem ist, dass, wenn ich eine GET-Anfrage an ihn mache, eine 502-Antwort { "message": "Internal server error" } zurückgegeben wird. In den Protokollen steht "Die Ausführung ist aufgrund eines Konfigurationsfehlers fehlgeschlagen: Falsch geformte Lambda-Proxy-Antwort".

46
jjbskir

Wenn Sie Malformed Lambda proxy response sehen, bedeutet dies normalerweise, dass Ihre Antwort von der Lambda-Funktion nicht mit dem Format übereinstimmt, das API Gateway erwartet

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

Wenn Sie die Lambda-Proxy-Integration nicht verwenden, können Sie sich an der API Gateway-Konsole anmelden und das Kontrollkästchen Lambda-Proxy-Integration deaktivieren.

Wenn Sie den intermittierenden Code Malformed Lambda proxy response sehen, kann dies bedeuten, dass die Anforderung an Ihre Lambda-Funktion von Lambda gedrosselt wurde und Sie eine gleichzeitige Erhöhung des Ausführungslimits für die Lambda-Funktion anfordern müssen.

61
Ka Hou Ieong

Wenn Lambda als Proxy verwendet wird, sollte das Antwortformat sein

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}

Hinweis: Der Rumpf sollte stringifiziert sein

31
selftaught91

Ja, ich denke, das liegt daran, dass Sie nicht wirklich eine richtige http-Antwort zurückgeben, weshalb Sie den Fehler erhalten.

ich persönlich benutze so eine Reihe von Funktionen:

    module.exports = {
        success: (result) => {
            return {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify(result),
            }
        },
        internalServerError: (msg) => {
            return {
                statusCode: 500,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify({
                    statusCode: 500,
                    error: 'Internal Server Error',
                    internalError: JSON.stringify(msg),
                }),
            }
        }
} // add more responses here.

Dann machst du einfach:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))
20
Mrk Fldig

Aus den AWS-Dokumenten

Rufen Sie in einer Lambda-Funktion in Node.js den Befehl .__ auf, um eine erfolgreiche Antwort zurückzugeben. Rückruf (null, {"statusCode": 200, "body": "results"}). Eine .__ werfen. Ausnahme, Rückruf (neuer Fehler ('interner Serverfehler')). Für ein clientseitiger Fehler, z. B. ein erforderlicher Parameter fehlt, können Sie .__ aufrufen. callback (null, {"statusCode": 400, "body": "Fehlende Parameter von ..."}), um den Fehler zurückzugeben, ohne eine Ausnahme auszulösen.

5
Jonathan

Ein sehr spezieller Fall, wenn Sie die Header direkt übergeben, besteht eine Chance, dass Sie diesen Header haben: 

"set-cookie": [ "........" ]

Aber Amazon braucht das:

"set-cookie": "[ \\"........\\" ]"

2
Miguel

Für alle anderen Personen, die Schwierigkeiten haben, wenn die Antwort gültig erscheint. Das funktioniert nicht:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})

aber das tut:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})

Es scheint auch, dass auf dem Antwortobjekt keine zusätzlichen Schlüssel vorhanden sein dürfen.

2
Ciryon

Ich hatte diesen Fehler, weil ich versehentlich die Variable ServerlessExpressLambdaFunctionName aus der CloudFormation AWS :: Serverless :: Api-Ressource entfernt habe. Der Kontext ist hier https://github.com/awslabs/aws-serverless-express "Führen Sie serverlose Anwendungen und REST - APIs mit Ihrem vorhandenen Node.js-Anwendungsframework über AWS Lambda und Amazon aus API-Gateway "

1
Mark

Wenn Sie Go mit https://github.com/aws/aws-lambda-go verwenden, müssen Sie events.APIGatewayProxyResponse verwenden. 

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}
1
Kohei Mikami

Ich habe alle oben genannten Vorschläge ausprobiert, aber es funktioniert nicht, während der Wert body nicht String ist.

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};
0
Long Nguyen

Eine häufige Ursache für den Fehler "Falsche Lambda-Proxy-Antwort" ist headersname__, bei dem es sich nicht um {String: String, ...} Schlüssel/Wert-Paare handelt.

Da set-cookie -Header mehrfach vorkommen können und müssen, werden sie in http.request.callback.response als der set-cookie -Schlüssel dargestellt, der den Wert ArrayNAME__ OF StringsNAME _ Wert anstelle eines einzelnen Stringname __ . Während dies für Entwickler funktioniert, versteht AWS API Gateway es nicht und gibt den Fehler "Fehlerhafte Lambda-Proxy-Antwort" aus.

Meine Lösung lautet:

function createHeaders(headers) {
  const singleValueHeaders = {}
  const multiValueHeaders = {}
  Object.entries(headers).forEach(([key, value]) => {
    const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders
    Object.assign(targetHeaders, { [key]: value })
  })

  return {
    headers: singleValueHeaders,
    multiValueHeaders,
  }
}

var output = {
  ...{
    "statusCode": response.statusCode,
    "body": responseString
  },
  ...createHeaders(response.headers)
}

Beachten Sie, dass der ... nicht Yada Yada Yada bedeutet. Es ist der ES6-Spread-Operator .

0
Bruno Bronosky

Falls das Obige bei niemandem funktioniert, bin ich auf diesen Fehler gestoßen, obwohl ich die Antwortvariable richtig eingestellt habe. 

Ich habe in meiner Funktion eine RDS-Datenbank aufgerufen. Es stellte sich heraus, dass das Problem die Sicherheitsgruppenregeln (eingehend) für diese Datenbank war. 

Möglicherweise möchten Sie die IP-Adressen einschränken, die auf die API zugreifen können. Wenn Sie jedoch schnell und fehlerfrei arbeiten möchten, um zu testen, ob die Änderung es korrigiert, können Sie festlegen, dass alle Änderungen akzeptiert werden Bereich für die Ports, um auch alle Ports zu akzeptieren, aber ich habe das in diesem Beispiel nicht gemacht):

 enter image description here

0
abe732