AWS Amplify returns 任何 Lambda 故障时的一般网络错误
AWS Amplify returns generic Network Error on any Lambda failure
我正在构建一个应用程序,该应用程序通过在 Web (React) 前端上使用的 AWS Amplify 与 AWS (API Gateway/Lambda) 上的无服务器 API 连接。
当请求成功时,一切正常(我想是肯定的)。没有 CORS 问题或任何问题。但是,如果我尝试 return 一个 "failed" 响应,我的前端不会收到该响应。它收到一个通用的 Network Error
,没有关于发生了什么的信息,并且控制台记录了一个失败。
我认为代码会更清楚这一点。我请求 API 使用这样的代码(放大在别处配置):
import { API } from 'aws-amplify';
...
API.get('apiName', path, options)
.then(response => {
// Whatever
})
.catch(err => {
// Whatever
})
在 Lambda 中,我正在 returning(Cloudwatch 验证了这一点,因为我在 运行 callback(null, responseObject)
之前登录)一个像这样的完整响应对象:
{
"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 都意味着请求在前端被捕获(良好),并且错误有 none 我 return 来自 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 失败相关的内容,这对我来说毫无意义,因为我遵循 完全 与成功案例相同的模式,只是具有更高的 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 网关的以下端点之一的屏幕截图(端点被白色遮挡):
我想确认这是 lambda-proxy 的意外行为。是否可能有一些设置搞砸了?
这最终取决于您如何配置 API 网关,例如Lambda 代理等。如果您未使用 Lambda 代理设置,则需要将这些错误 responses/codes 映射到 API 网关,请在此处查看详细的 post:
https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/
如果您使用的是 Lambda 代理,您将 return 作为来自 Lambda 的特定类型的代理响应:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
想通了!返回的错误对象(通用 500
和 NetworkError
包含 我构造的错误,在 response
键下)。
因此,如果我记录 error.response
,我会得到完全构造的错误对象,它有自己的消息和 statusCode
,即使错误对象本身有一个 code
500
和 Error: Network Error
的消息,错误捕获过程似乎在控制台中抛出了不准确的错误日志(CORB 东西)。
奇怪。不确定这是预期的 Lambda 行为,还是 Amplify 的某些行为,或者我做错了什么,但如果其他人遇到此问题,我希望这会有所帮助!
EDIT - 显然这是预期的放大行为,我在文档中错过了。
但我发现了另一个似乎是错误的问题。只有当我 不 在请求选项中指定 headers
时,才会显示此响应键。换句话说,此请求 returns 一个带有 response
键的 error
:
API.get('my-api', '/path')
但是这个 returns 没有密钥的错误:
API.get('my-api', '/path', { headers: { 'Content-Type': 'application/json' } })
很奇怪,但对我来说是真的。甚至 other 选项都很好,但是 headers 选项似乎把事情搞砸了(而且只针对错误响应)。
如果您正在使用 API 网关并且 运行 遇到此问题,请确保更新 API 网关的“网关响应”默认 5XX 和默认 4XX headers 以包含正确的响应 headers(and/or 消息)——否则 Access-Control-Allow-Origin
将不会在错误响应时发送,您的浏览器将抛出“网络错误”。
例如,将默认 5XX 和 4XX 的响应 headers 设置为:
Response header: Access-Control-Allow-Origin
Value: '*'
更新这些默认 header 值解决了我的问题,现在正在解决正确的错误消息。
我正在构建一个应用程序,该应用程序通过在 Web (React) 前端上使用的 AWS Amplify 与 AWS (API Gateway/Lambda) 上的无服务器 API 连接。
当请求成功时,一切正常(我想是肯定的)。没有 CORS 问题或任何问题。但是,如果我尝试 return 一个 "failed" 响应,我的前端不会收到该响应。它收到一个通用的 Network Error
,没有关于发生了什么的信息,并且控制台记录了一个失败。
我认为代码会更清楚这一点。我请求 API 使用这样的代码(放大在别处配置):
import { API } from 'aws-amplify';
...
API.get('apiName', path, options)
.then(response => {
// Whatever
})
.catch(err => {
// Whatever
})
在 Lambda 中,我正在 returning(Cloudwatch 验证了这一点,因为我在 运行 callback(null, responseObject)
之前登录)一个像这样的完整响应对象:
{
"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 都意味着请求在前端被捕获(良好),并且错误有 none 我 return 来自 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 失败相关的内容,这对我来说毫无意义,因为我遵循 完全 与成功案例相同的模式,只是具有更高的 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 网关的以下端点之一的屏幕截图(端点被白色遮挡):
我想确认这是 lambda-proxy 的意外行为。是否可能有一些设置搞砸了?
这最终取决于您如何配置 API 网关,例如Lambda 代理等。如果您未使用 Lambda 代理设置,则需要将这些错误 responses/codes 映射到 API 网关,请在此处查看详细的 post: https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/
如果您使用的是 Lambda 代理,您将 return 作为来自 Lambda 的特定类型的代理响应:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
想通了!返回的错误对象(通用 500
和 NetworkError
包含 我构造的错误,在 response
键下)。
因此,如果我记录 error.response
,我会得到完全构造的错误对象,它有自己的消息和 statusCode
,即使错误对象本身有一个 code
500
和 Error: Network Error
的消息,错误捕获过程似乎在控制台中抛出了不准确的错误日志(CORB 东西)。
奇怪。不确定这是预期的 Lambda 行为,还是 Amplify 的某些行为,或者我做错了什么,但如果其他人遇到此问题,我希望这会有所帮助!
EDIT - 显然这是预期的放大行为,我在文档中错过了。
但我发现了另一个似乎是错误的问题。只有当我 不 在请求选项中指定 headers
时,才会显示此响应键。换句话说,此请求 returns 一个带有 response
键的 error
:
API.get('my-api', '/path')
但是这个 returns 没有密钥的错误:
API.get('my-api', '/path', { headers: { 'Content-Type': 'application/json' } })
很奇怪,但对我来说是真的。甚至 other 选项都很好,但是 headers 选项似乎把事情搞砸了(而且只针对错误响应)。
如果您正在使用 API 网关并且 运行 遇到此问题,请确保更新 API 网关的“网关响应”默认 5XX 和默认 4XX headers 以包含正确的响应 headers(and/or 消息)——否则 Access-Control-Allow-Origin
将不会在错误响应时发送,您的浏览器将抛出“网络错误”。
例如,将默认 5XX 和 4XX 的响应 headers 设置为:
Response header: Access-Control-Allow-Origin
Value: '*'
更新这些默认 header 值解决了我的问题,现在正在解决正确的错误消息。