2017-10-11 14 views
1

J'ai une fonction lambda sans serveur écrite dans Node.JS.Quelle est la bonne façon de renvoyer les codes d'erreur HTTP dans lambda sans serveur

Quelle est la meilleure façon de renvoyer des codes d'erreur?

Le modèle que j'utilise en ce moment (! et cela fonctionne) est:

module.exports.endpoint = (event, context, callback) => { 
    const response = { 
     statusCode: 404, 
     body: JSON.stringify({ message: 'Hello World!' }) 
    }; 
    callback(null, response); 
} 

Quand je fais un appel, par exemple de POSTMAN, à mon point final je reçois:

Status: 404 Not Foundest exactement ce que j'attends.

De plus, dans les journaux que je peux voir:

Serverless: GET/(λ: get) 
Serverless: [404] {"statusCode":404,"body":"{\"message\":\"Hello World!\"}"} 

qui fonctionne bien.

Ce qui me dérange, c'est que je passe null comme erreur. En regardant dans quelques autres tutoriels/exemples que j'ai trouvé des motifs comme:

https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/

https://serverless.com/framework/docs/providers/aws/events/apigateway/

callback ("the sky is falling!");

callback("[BadRequest] Validation error: Missing field 'name'");

callback("[404] Not Found");

callback(new Error('[404] Not found'));

callback(JSON.stringify(myErrorObj));

Tous font sens parfait et vous pouvez spécifier Code d'état HTTP - encore ce que je reçois est Code d'état HTTP 200 à la fin. Quand je regarde les journaux, je vois que l'erreur a été suivie immédiatement après avec 200:

Serverless: GET/(λ: get) 
Serverless: Failure: the sky is falling! 
Serverless: Replying 200 

Serverless: GET/(λ: get) 
Serverless: Failure: [BadRequest] Validation error: Missing field 'name' 
Serverless: Replying 200 

Serverless: GET/(λ: get) 
Serverless: Failure: [404] Not Found 
Serverless: Replying 200 

Serverless: GET/(λ: get) 
Serverless: Failure: [404] Not found 
Serverless: Replying 200 

Serverless: GET/(λ: get) 
Serverless: Failure: {"errorType":"InternalServerError","httpStatus":500,"message":"An unknown error has occurred. Please try again."} 
Serverless: Replying 200 

Dans cet endroit que j'ai trouvé explication suivante: https://github.com/serverless/serverless/issues/4119

Si vous voulez répondre avec erreurs HTTP dans ce cas, vous devez encode l'erreur HTTP de réponse Lambda comme réussie

par exemple suivant:

Sample 403: 
callback(null, { statusCode: 403, body: "Forbidden", headers: { "Content-Type": "text/plain" } }); 
Sample 404: 
callback(null, { statusCode: 400 }); 

Donc c'est fondamentalement la même manière que j'ai. Par souci d'exhaustivité, je peux ajouter qu'il y a aussi beaucoup d'exemples qui utilisent context.fail(result) ou context.succeed(result) - mais de ce que j'ai recueilli context est déprécié et ne devrait pas être utilisé (même si cela fonctionne toujours).

Quel est le point d'utiliser callback(error)?

Répondre

1

Si vous voulez répondre avec des erreurs HTTP dans ce cas, vous devez coder l'erreur HTTP comme réponse réussie Lambda

Cette façon de gestion des erreurs est spécifique à la passerelle API. Comme dans les serveurs Web de nœuds traditionnels (par exemple, express), vous pouvez lancer une erreur en utilisant throw new Error ('Invalid Payload') et un middleware le convertit habituellement en une réponse HTTP avec le bon état de réponse.

Dans la passerelle API Lambda, ce qui peut être écrit comme ça ...

function createResponse(status, body) { 
    return { 
    headers: { 
     'Access-Control-Allow-Origin': '*', 
    } 
    statusCode: status, 
    body: JSON.stringify(body) 
    } 
} 

module.exports.endpoint = (event, context, callback) => { 
    try { 
     return callback(null, createResponse(200, processEvent(event))) 
    } except (e) 
     console.error(e) 

     return callback(null, createResponse(500, { 
     error: 'Internal Server Error', 
     })) 
} 

Fondamentalement, il est une erreur traitée. La fonction lambda a réussi mais la requête a échoué (peut-être 400, 404 ou 500). Vous devez toujours traiter les erreurs, ou si votre gestionnaire tombe en panne (en raison d'une erreur d'exécution, d'une erreur de syntaxe ou d'une erreur de traitement), votre utilisateur obtiendra une réponse inattendue (500 ou 502) que vous utiliserez probablement. Je ne veux pas. Ceci étant dit, n'oubliez pas que Lambda n'est pas seulement utilisé pour API Gateway. callback(error) est utilisé pour les Lambda non déclenchées par la passerelle API. Par exemple, si vous avez un Lambda déclenché par le SNS, vous pouvez renvoyer callback('Any error message here') et il informera le SNS qu'il a échoué et que le SNS peut réessayer l'invocation.

+0

Je vois que vous utilisez de la même façon à la fin: 'return callback (null, createResponse)' - passe 'null' comme erreur et ensuite erreur réelle va au résultat. – iaforek

+0

Oui. Comme je l'ai dit, vous devez gérer les erreurs pour API Gateway Lambdas. – dashmug

+0

@iaforek Avec quoi êtes-vous encore confondu? – dashmug