AWS Amplify возвращает общую сетевую ошибку при любом лямбда-сбое - PullRequest
0 голосов
/ 24 августа 2018

Я создаю приложение, которое подключается с помощью бессерверного API на AWS (API Gateway / Lambda) через AWS Amplify, которое используется в веб-интерфейсе (React).

Когда запрос успешен, все работает просто отлично (определенно, я полагаю). Там нет вопросов CORS или что-нибудь. Но если я попытаюсь вернуть «неудачный» ответ, мой интерфейс не получит этот ответ. Он получает общий Network Error без информации о том, что произошло, и консоль регистрирует ошибку.

Я думаю, что код будет иметь больше смысла в этом. Я запрашиваю к API, используя такой код (Amplify настроен в другом месте):

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

В Lambda я возвращаю (и 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 означает, что запрос перехватывается на интерфейсе (хорошо), и что ошибка не содержит никакой информации, которую я возвращаю из Лямбда (плохо).

Консоль также регистрирует ошибки:

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".

Есть идеи, что здесь происходит? Очень печально не иметь доступа к настоящей информативной ошибке на веб-интерфейсе. Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которая будет полезна для решения этой проблемы.

РЕДАКТИРОВАТЬ - следуя приведенным ниже комментариям @ Майкла, я проверил, использует ли мое приложение лямбда или лямбда-прокси, и на самом ли деле он использует лямбда-прокси, который должен не производит такое поведение, насколько я понимаю.

Вот некоторый код в моем файле 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

Я хочу подтвердить, что это неожиданное поведение для лямбда-прокси. Возможно, есть какие-то настройки, которые все портят?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Разобрался! Возвращающийся объект ошибки (общие 500 и NetworkError содержали мою созданную ошибку под ключом response).

Так что, если я зарегистрирую error.response, я получу полностью построенный объект ошибки с его собственным сообщением и statusCode, даже если сам объект ошибки имеет code 500 и сообщение Error: Network Error, и процесс перехвата ошибок, кажется, выбрасывает неточные журналы ошибок (CORB вещи) в консоли.

Weird. Не уверен, что это ожидаемое поведение лямбды, или что-то с Amplify, или что-то я делаю не так, но если кто-то еще столкнется с этой проблемой, я надеюсь, что это поможет!

РЕДАКТИРОВАТЬ - Очевидно, это ожидаемое усиление поведения, которое я пропустил в документах.

Но я обнаружил еще одну проблему, которая кажется ошибкой. Этот ключ ответа появляется только тогда, когда я не указываю headers в параметрах запроса. Другими словами, этот запрос возвращает error с ключом response:

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

Но этот возвращает ошибку без ключа:

API.get('my-api', '/path', { headers: { 'Content-Type': 'application/json' } })

Очень странно, но это правда для меня. Даже другие опции хороши, но опция заголовков, кажется, запутывает вещи (и только для ответа об ошибке).

0 голосов
/ 31 августа 2018

В конечном итоге это зависит от того, как вы настраиваете свой API-шлюз, например, Lambda-прокси и т. Д. Если вы НЕ используете настройку Lambda-прокси, вам необходимо отобразить эти ответы / коды ошибок в API-шлюзе, см. Обширный пост на эту тему.здесь: https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/

Если вы используете лямбда-прокси, вы просто вернетесь как особый тип ответа прокси от Lambda: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html

...