代码之家  ›  专栏  ›  技术社区  ›  Eric

通过带有Lambda代理集成的API网关从AWS Lambda抛出错误

  •  0
  • Eric  · 技术社区  · 6 年前

    我有一个基本的AWS Lambda函数(Java 8),它要么返回成功消息,要么返回错误。我希望它抛出一个错误,这样实际的Lambda函数就会失败。然而,我不知道如何将这个错误对象从lambda函数通过API网关“传递”到客户端。我一直在尝试更改网关响应,但到目前为止还没有成功。

    因为我需要启用Lambda代理集成,所以我没有成功。我已经通读了 guide on error handling ,很多人都喜欢它,但它们似乎都关闭了Lambda代理集成。

    我的代码:

    package com.amazonaws.lambda.demo;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
    import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
    
    public class LambdaFunctionHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    
          @Override
          public APIGatewayProxyResponseEvent handleRequest( APIGatewayProxyRequestEvent input, Context context ) {
              APIGatewayProxyResponseEvent response = getSuccessResponse();
    
              // Fake some error happening that causes a runtime exception
              Map<String, Object> errorObj = getErrorObjectMap(context);
              JSONObject json = new JSONObject(errorObj);
              throw new RuntimeException(json.toString());
              //return response;
    
          }
    
          private APIGatewayProxyResponseEvent getSuccessResponse() {
    
                Map<String, String> headers = new HashMap<>();
                headers.put("Content-type", "text/plain");
    
                APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
                        .withStatusCode(200)
                        .withHeaders(headers)
                        .withBody("Success!")
                        .withIsBase64Encoded(Boolean.FALSE);
    
    
    
                return response;
          }
    
          private Map<String, Object> getErrorObjectMap(Context context){
                Map<String, Object> errorPayload = new HashMap<>();
                errorPayload.put("errorType", "BadRequest");
                errorPayload.put("httpStatus", 400);
                errorPayload.put("requestId", context.getAwsRequestId());
                errorPayload.put("message", "An unknown error has occurred. Please try again.");
    
                return errorPayload;
          }
    }
    

    我已尝试将默认4XX网关响应以及所有其他响应更改为自定义消息。然而,它没有起作用。我仍然只是得到了 {"message": "Internal server error"} 消息。

    因为请求是代理的,所以我无法在Integration Response中添加模板。因此,我不确定如何处理这些错误。目前,我只返回一个正常的响应对象。这可以工作,但Lambda函数不知道它失败了。

    Map<String, String> headers = new HashMap<>();
    headers.put("Content-type", "text/plain");
    
    APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
                        .withStatusCode(400)
                        .withHeaders(headers)
                        .withBody("Error!")
                        .withIsBase64Encoded(Boolean.FALSE);
    

    如何在lambda函数中抛出错误并在API网关中进行处理,以便将自定义消息发送到客户端?

    0 回复  |  直到 6 年前
        1
  •  2
  •   DWilches    6 年前

    使用时返回错误响应的工作方式不同 Lambda代理集成 。您不会抛出异常,但会返回一个包含异常信息的Map。

    如果启用了代理集成并抛出异常,则将假定Lambda函数意外失败(因此收到错误500)。

    试试这段代码:

    package org.example.basicapp;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class LambdaFunctionHandler {
    
        public static Map<String, Object> handleRequest(final Map<String, Object> request) {
    
            final Map<String, Object> requestContext = (Map) request.get("requestContext");
    
            final Map<String, Object> responseHeaders = new HashMap<>();
            responseHeaders.put("x-OriginalAwsRequestId", requestContext.get("requestId"));
    
            final Map<String, Object> responseMap = new HashMap<>();
            responseMap.put("statusCode", 400);
            responseMap.put("headers", responseHeaders);
            responseMap.put("body", "An unknown error has occurred. Please try again.");
            return responseMap;
        }
    }
    
    

    当在API网关中测试时,将显示这一点:

    enter image description here

    推荐文章