任何Lambda故障,AWS Amplify都会返回通用网络错误

时间:2018-08-24 18:13:37

标签: reactjs amazon-web-services aws-lambda serverless-framework aws-amplify

我正在构建一个应用程序,该应用程序通过Web前端上使用的AWS Amplify与AWS上的无服务器API(API网关/ Lambda)连接。

请求成功后,一切正常(我想应该是明确的)。没有CORS问题。但是,如果我尝试返回“失败”响应,则前端不会收到该响应。它接收到通用Network Error,但没有有关发生的任何信息,并且控制台记录了故障。

我认为代码将对此更加有意义。我使用这样的代码(在其他地方配置了Ampl)向API请求:

import { API } from 'aws-amplify';
...
API.get('apiName', path, options)
  .then(response => {
     // Whatever
  })
  .catch(err => {
     // Whatever
  })

在Lambda中,我将返回一个完整的响应对象(在运行callback(null, responseObject)之前,Cloudwatch会进行验证,就像我登录时一样):

{
    "statusCode": 200,
    "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": true
    },
    "body": "{ /* whatever */ }"
}

或者这个:

{
    "statusCode": 500,
    "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": true
    },
    "body": "{ /* error here */ }"
}

200情况下,响应完美地到达了我的前端(在.then函数中显示为response)。在500(或一般错误)的情况下,.catch被称为 err对象不是我所输入的 响应正文,而是一个普通的Network Error,没有相关信息(或状态码):

Error: Network Error
    at createError (createError.js:16)
    at XMLHttpRequest.handleError (xhr.js:87)

为澄清起见,只需将statusCode 从200更改为400,都意味着该请求在前端被捕获(良好),并且该错误没有我所需要的信息从Lambda(坏)返回。

控制台还会记录错误:

DELETE https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint 403 ()

Failed to load https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.

它还会记录与CORS故障相关的信息,这对我来说是没有意义的,因为我遵循的是与成功案例相同的 exact 模式,只是使用更高的statusCode

Cross-Origin Read Blocking (CORB) blocked cross-origin response https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint with MIME type application/json.
XHR failed loading: DELETE "https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint".

知道这里发生了什么吗?不能访问前端的实际信息错误确实令人沮丧。请让我知道是否还有其他信息可以帮助解决此问题。

编辑-根据下面@Michael的反馈,我检查了我的应用是否使用了lambda或lambda-proxy,实际上是使用了lambda-proxy,应该不是会产生这种行为。

在我的serverless.yml文件中有一些代码,

functions:
  projectsGetAll:
    handler: handlers/projects/getAll.handler
    events:
      - http:
          path: projects
          method: get
          cors: true
          authorizer: aws_iam

这是来自AWS API Gateway的以下端点之一的屏幕截图(端点为空白):

enter image description here

我想确认这是lambda-proxy的意外行为。可能有某些设置使事情变糟了吗?

3 个答案:

答案 0 :(得分:1)

这最终取决于您如何配置API网关,例如Lambda代理等。如果您未使用Lambda代理设置,则需要在API网关内映射这些错误响应/代码,请参阅此处的大量文章: https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/

如果您使用的是Lambda代理,则只是从Lambda作为特定类型的代理响应返回:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html

答案 1 :(得分:1)

如果您使用 API Gateway 并遇到此问题,请确保更新 API Gateway 的“网关响应”默认 5XX 和默认 4XX 标头以包含正确的响应标头(和/或消息)--否则 { {1}} 不会在错误响应时发送,您的浏览器将抛出“网络错误”。

例如,将默认 5XX 和 4XX 的响应标头设置为:

Access-Control-Allow-Origin

更新这些默认标头值解决了我的问题,现在正在解决正确的错误消息。

答案 2 :(得分:0)

想通了!错误对象又回来了(在500键下,通用的NetworkErrorresponse包含了我构造的错误)。

因此,如果我登录error.response,即使错误对象本身的statusCode为{{1},也会得到带有其自身消息和code的完全构造的错误对象。 }和500的消息,错误捕获过程似乎在控制台中抛出了不准确的错误日志(CORB内容)。

很奇怪。不知道这是预期的Lambda行为,还是Amplify发生的事情,或者我做错了什么,但是如果有人遇到此问题,希望对您有所帮助!

编辑-显然,这是预期的放大行为,我在文档中错过了该行为。

但是我发现了另一个似乎是错误的问题。仅当我在请求选项中指定Error: Network Error时,才会显示此响应键。换句话说,此请求返回带有headers键的error

response

但是这个返回没有密钥的错误:

API.get('my-api', '/path')

很奇怪,但对我来说是正确的。甚至 other 选项都可以,但是headers选项似乎使事情变得混乱(并且仅用于错误响应)。