Ошибка api как решить

Adding an API Gateway to your application is a good way to centralize some work you usually have to do for all of your API routes, like authentication or validation. But like every software system, it comes with its own problems. Solving errors in the cloud isn’t always straightforward, and API Gateway isn’t an exception.

What is AWS API Gateway?

AWS API Gateway is an HTTP gateway, and as such, it uses the well-known HTTP status codes to convey its errors to you. Errors in the range of 400 to 499 usually point to a problem with the API client, and errors in the range of 500 to 599 mean something on the server is wrong.

This is a rule of thumb, and if you don’t have any logic bugs in your backend, it holds. But nobody is perfect, and so it could happen that a 400 code still means your client is right and your backend is wrong. But let’s not get ahead of us and look into the errors, case by case.

what is aws ap gateway

Handling API Gateway 400 Error: Bad Request

The 400 error is probably the broadest of the client errors. Depending on what AWS service API Gateway is integrating with for the URL, it can mean many things.

A retry usually doesn’t help because it means the request doesn’t match what that specific API Gateway integration is expecting, and sending it again wouldn’t change that.

Reasons for this error include:

  • Invalid JSON, like missing commas and such.
  • Missing fields, when the upstream service has required a field you missed
  • Wrong data types, when you send a string instead of a number
  • Invalid characters, like using whitespaces in identifiers

You can find the required fields, expected data types, and valid characters for a field in the documentation of the AWS service you integrated with API Gateway.

Handling API Gateway 403 Error: Access Denied

This error is also known as “Forbidden” and implies some permission issue. Every resource you provision in AWS has an IAM role. This role defines what that resource can access and how it can access it. Your API Gateway has an IAM role too, and if it’s not configured correctly, it can prevent API Gateway from integrating with a service.

Again, a retry doesn’t help here.

If you use end-user authentication with AWS Cognito, every request will get a temporary role related to the Cognito user who issued the request. If this role isn’t configured correctly, it can also prevent users from accessing specific resources.

If you’re using a custom Lambda authorizer in your API Gateway, this error code could also relate to a problem in that Lambda function.

Handling API Gateway 404 Error: Not Found

The 404 error usually means your URL is wrong. Probably in 99% of the cases

If you’re sure the URL is right, but you’re still getting the error, it could also be related to the service you integrate with API Gateway when you try to access data in these services that aren’t there.

A retry only solves this problem if the 404 comes from a race condition. When you told the backend to create a resource, you wanted to access it with the next request, but the request was too soon, and the thing you created isn’t there yet. Such issues happen with eventually consistent data stores like DynamoDB. 

The more expensive consistent reads of DynamoDB usually solve this problem.

Handling API Gateway 409 Error: Conflict

The 409 status indicates that your request is trying to do something that conflicts with a resource’s current state. A resource could be a record in a DynamoDB table that’s integrated with your API. It could be that you tried to create a resource with a specific ID that already exists.

The 409 error is also related to something called a callers reference. This reference is used to mark a request, so it gets only executed once. If you send it and don’t get an answer from the API, you don’t know if the request got lost before or after it made its way to the API. This usually leads to a retry. If the API hasn’t seen the caller reference the last time, it will simply execute it and respond with an appropriate status code. But if the API has seen the caller reference, it gives you a 409 status code to indicate your request was already accepted when you sent it the first time.

So, a retry usually won’t solve this problem and can even be the source of this error code in the first place.

Handling API Gateway 429 Error: Limit Exceeded

There are two 429 errors you could get from API Gateway. The first one is called “Limit Exceeded Exception,” which indicates that you went over an API quota.

API Gateway allows access control via API keys. When creating such a key, you can also define a usage quota such as 1000 requests per week. If this quota is reached, the API gateway will respond with a 429.

Normally a retry doesn’t solve this problem. You either have to increase the quota for the key, or you have to wait until the next usage period starts.

The best way to get around this issue is to keep your API requests monitored and counted. Check how many requests you send and if you really need to send so many. You can also try to cache responses so that you can reuse them instead of sending duplicate requests that count to your key’s quota. 

Handling API Gateway 429 Error: Too Many Requests

The second 429 error is of temporary nature. You would get it if you sent too many requests at once. For example, if you have an API endpoint connected to a Lambda function, this function has a predefined limit of 1000 concurrent invocations.

If you send 1001 in parallel, you get a 429 error, but depending on the time this Lambda function takes to handle a request, you can retry some time later and get a free slot again.

Again, API keys can have limits too. If you got a key that only allows for 10 concurrent requests, the upstream service could handle millions, but your 11th parallel request wouldn’t go through.

Try to monitor your request so you see when they get close to the limit of your services, and try to cache requests on your clients so that they won’t hammer the API.

api gateway detecting issues

Did you know Dashbird will detect API Gateway issues and alert them to you?

Handling API Gateway 500 Error: Internal Server Error

The 500 status code might be the most used and most generic HTTP error on this planet. If you get it from an API endpoint that integrates with AWS Lambda, it usually means your code buggy.

The next source for this error is inconsistent error mapping. Many of the errors we talked about here can become a 500 error when finally landing on your client as a response. You’ll get a “limit exceeded,” but it will have a 500 status code instead of 429. So you have to extract the right error out of this response, check what the real cause is, and then look at how to solve it.

Since the error can be anything really, a retry can technically solve that problem, but usually, it doesn’t.

If you monitor your system carefully and get one of these every few million requests, it could be that cosmic rays flipped some bits or whatever. Still, if you see a 500 status code more often than that, it’s crucial to investigate; it can very well point to an inconsistency that will blow up sooner or later.

Handling API Gateway 502 Error: Bad Gateway

A 502 error code is related to the service your API Gateway integrates with. It means that API Gateway couldn’t understand the response.

For example, when you throw an error in a Lambda function or the resolved value has an invalid structure, it can lead to a 502 error. If you used EC2 or ECS/EKS, it could also be that API Gateway can’t connect to the VM or container because they aren’t running (correctly).

Retries can help, especially when integrated services are currently restarting. 

Handling API Gateway 503 Error: Service Unavailable

If you see a 503 error, most of the time, it means the service you’re integrating takes too long to answer. 

API Gateway has a maximum hard limit of 30 seconds timeouts. If your service can’t respond in under 30 seconds, API Gateway will assume it’s unavailable and stop waiting.

If the work your service does takes around 30 seconds, you should handle things asynchronously. Respond with a 202 accepted and give the client a way to fetch the results later.

If your service usually responds well below 30 seconds but only occasionally goes over the limit, you can solve the problem with retries.

Handling API Gateway 504 Error: Endpoint Request Timed-out 

The 504 status code is a bit like 503. The difference is that 504 indicates a DNS or network problem, and 503 indicates a performance problem.

Again, this can be temporary, and a retry might solve it. After all, the internet isn’t 100% stable. 

But you usually see that issue when an integrated service isn’t running, or you got the IP or hostname wrong, either because you entered the wrong or they changed somehow after you entered them.

Conclusion

We went over all the API Gateway errors you will probably encounter, and like with anything debugging-related, things can get quite messy — especially if you have countless rows of logs to sift through.

api gateway metrics dashboard

The good news is that Dashbird integrates well with API Gateway monitoring and delivers actionable insights straight to your Slack or SMS when things go awry. 

Dashbird also works with AWS as their Advanced Technology Partner and uses the AWS Well-Architected Framework to ensure you’re on track to performance and cost optimization. If you want to try Dashbird out, it’s free for the first 1 million invocations per month.

Read our blog

Introducing easy custom event monitoring for serverless applications.

Today we are excited to announce scheduled searches – a new feature on Dashbird that allows you to track any log event across your stack, turn it into time-series metric and also configure alert notifications based on it.

Why and How to Monitor Amazon OpenSearch Service

One of the most vital aspects to monitor is the metrics. You should know how your cluster performs and if it can keep up with the traffic. Learn more about monitoring Amazon OpenSearch Service.

Why and How to Monitor AWS Elastic Load Balancing

Dashbird recently added support for ELB, so now you can keep track of your load balancers in one central place. It comes with all the information you expect from AWS monitoring services and more!

More articles

Время на прочтение
6 мин

Количество просмотров 16K

Почти все разработчики так или иначе постоянно работают с api по http, клиентские разработчики работают с api backend своего сайта или приложения, а бэкендеры «дергают» бэкенды других сервисов, как внутренних, так и внешних. И мне кажется, одна из самых главных вещей в хорошем API это формат передачи ошибок. Ведь если это сделано плохо/неудобно, то разработчик, использующий это API, скорее всего не обработает ошибки, а клиенты будут пользоваться молчаливо ломающимся продуктом.

За 7 лет я как поддерживал множество legacy API, так и разрабатывал c нуля. И я поработал, наверное, с большинством стратегий по возвращению ошибок, но каждая из них создавала дискомфорт в той или иной мере. В последнее время я нащупал оптимальный вариант, о котором и хочу рассказать, но с начала расскажу о двух наиболее популярных вариантах.

№1: HTTP статусы

Если почитать апологетов REST, то для кодов ошибок надо использовать HTTP статусы, а текст ошибки отдавать в теле или в специальном заголовке. Например:

Success:

HTTP 200 GET /v1/user/1
Body: { name: 'Вася' }

Error:

HTTP 404 GET /v1/user/1
Body: 'Не найден пользователь'

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

Http статусы предназначались для описания ошибок при передаче данных, а про логику вашего приложения никто не думал. Статусов явно не хватает для описания всего разнообразия ошибок в вашем проекте, да они и не были для этого предназначены. И тут начинается натягивание «совы на глобус»: все начинают спорить, какой статус ошибки дать в том или ином случае. Пример: Есть API для task manager. Какой статус надо вернуть в случае, если пользователь хочет взять задачу, а ее уже взял в работу другой пользователь? Ссылка на http статусы. И таких проблемных примеров можно придумать много.

REST скорее концепция, чем формат общения из чего следует неоднозначность использования статусов. Разработчики используют статусы как им заблагорассудится. Например, некоторые API при отсутствии сущности возвращают 404 и текст ошибки, а некоторые 200 и пустое тело.

Бэкенд разработчику в проекте непросто выбрать статус для ошибки, а клиентскому разработчику неочевидно какой статус предназначен для того или иного типа ошибок бизнес-логики. По-хорошему в проекте придется держать enum для того, чтобы описать какие ошибки относятся к тому или иному статусу.

Когда бизнес-логика приложения усложняется, начинают делать как-то так:

HTTP 400 PUT /v1/task/1 { status: 'doing' }
Body: { error_code: '12', error_message: 'Задача уже взята другим исполнителем' } 

Из-за ограниченности http статусов разработчики начинают вводить “свои” коды ошибок для каждого статуса и передавать их в теле ответа. Другими словами, пользователю API приходится писать нечто подобное:

if (status === 200) {
  // Success
} else if (status === 500) {
  // some code
} else if (status === 400) {
  if (body.error_code === 1) {
    // some code
  } else if (body.error_code === 2) {
    // some code
  } else {
    // some code
  }
} else if (status === 404) {
  // some code
} else {
  // some code
}

Из-за этого ветвление клиентского кода начинает стремительно расти: множество http статусов и множество кодов в самом сообщении. Для каждого ошибочного http статуса необходимо проверить наличие кодов ошибок в теле сообщения. От комбинаторного взрыва начинает конкретно пухнуть башка! А значит обработку ошибок скорее всего сведут к сообщению типа “Произошла ошибка” или к молчаливому некорректному поведению.

Многие системы мониторинга сервисов привязываются к http статусам, но это не помогает в мониторинге, если статусы используются для описания ошибок бизнес логики. Например, у нас резкий всплеск ошибок 429 на графике.  Это началась DDOS атака, или кто-то из разработчиков выбрал неудачный статус?

Итог:  Начать с таким подходом легко и просто и для простого API это вполне подойдет. Но если логика стала сложнее, то использование статусов для описания того, что не укладывается в заданные рамки протокола http приводит к неоднозначности использования и последующим костылям для работы с ошибками. Или что еще хуже к формализму, что ведет к неприятному пользовательскому опыту.

№2: На все 200

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

Вариант 1:

Success:
HTTP 200 GET /v1/user/1
Body: { ok: true, data: { name: 'Вася' } }

Error:
HTTP 200 GET /v1/user/1
Body: { ok: false, error: { code: 1, msg: 'Не найден пользователь' } }

Вариант 2:

Success:
HTTP 200 GET /v1/user/1
Body: { data: { name: 'Вася' }, error: null }

Error:
HTTP 200 GET /v1/user/1
Body: { data: null, error: { code: 1, msg: 'Не найден пользователь' } }

На самом деле формат зависит от вас или от выбранной библиотеки для реализации коммуникации, например JSON-API.

Звучит здорово, мы теперь отвязались от http статусов и можем спокойно ввести свои коды ошибок. У нас больше нет проблемы “впихнуть невпихуемое”. Выбор нового типа ошибки не вызывает споров, а сводится просто к введению нового числового номера (например, последовательно) или строковой константы. Например:

module.exports = {
  NOT_FOUND: 1,
  VALIDATION: 2,
 // ….
}

module.exports = {
  NOT_FOUND: ‘NOT_AUTHORIZED’,
  VALIDATION: ‘VALIDATION’,
 // ….
}

Клиентские разработчики просто основываясь на кодах ошибок могут создать классы/типы ошибок и притом не бояться, что сервер вернет один и тот же код для разных типов ошибок (из-за бедности http статусов).

Обработка ошибок становится менее ветвящейся, множество http статусов превратились в два: 200 и все остальные (ошибки транспорта).

if (status === 200) {
  if (body.error) {
    var error = body.error;
    if (error.code === 1) {
      // some code
    } else if (error.code === 2) {
      // some code
    } else {
      // some code
    }
  } else {
    // Success
  }
} else {
  // transport erros
}

В некоторых случаях, если есть библиотека десериализации данных, она может взять часть работы на себя. Писать SDK вокруг такого подхода проще нежели вокруг той или иной имплементации REST, ведь реализация зависит от того, как это видел автор. Кроме того, теперь никто не вызовет случайное срабатывание alert в мониторинге из-за того, что выбрал неудачный код ошибки.

Но неудобства тоже есть:

  • Избыточность полей при передаче данных, т.е. нужно всегда передавать 2 поля: для данных и для ошибки. Это усложняет чтение логов и написание документации.

  • При использовании средств отладки (Chrome DevTools) или других подобных инструментов вы не сможете быстро найти ошибочные запросы бизнес логики, придется обязательно заглянуть в тело ответа (ведь всегда 200)

  • Мониторинг теперь точно будет срабатывать только на ошибки транспорта, а не бизнес-логики, но для мониторинга логики надо будет дописывать парсинг тела сообщения.

В некоторых случаях данный подход вырождается в RPC, то есть по сути вообще отказываются от использования url и шлют все на один url методом POST, а в теле сообщения передают все параметры. Мне кажется это не правильным, ведь url это прекрасный именованный namespace, зачем от этого отказываться, не понятно?! Кроме того, RPC создает проблемы:

  • нельзя кэшировать по http GET запросы, так как замешали чтение и запись в один метод POST

  • нельзя делать повторы для неудавшихся GET запросов (на backend) на реверс-прокси (например, nginx) по указанной выше причине

  • имеются проблемы с документированием – swagger и  ApiDoc не подходят, а удобных аналогов я не нашел

Итог: Для сложной бизнес-логики с большим количеством типов ошибок такой подход лучше, чем расплывчатый REST, не зря в проектах c “разухабистой” бизнес-логикой  часто именно такой подход и используют.

№3: Смешанный

Возьмем лучшее от двух миров. Мы выберем один http статус, например, 400 или 422 для всех ошибок бизнес-логики, а в теле ответа будем указывать код ошибки или строковую константу. Например:

Success:

HTTP 200 /v1/user/1
Body: { name: 'Вася' }

Error:

HTTP 400 /v1/user/1
Body: { error: { code: 1, msg: 'Не найден пользователь' } }

Коды:

  • 200 – успех

  • 400 – ошибка бизнес логики

  • остальное ошибки в транспорте

Тело ответа для удачного запроса у нас имеет произвольную структуру, а вот для ошибки есть четкая  схема. Мы избавляемся от избыточности данных (поле ошибки/данных) благодаря использованию http статуса в сравнении со вторым вариантом. Клиентский код упрощается в плане обработки ошибки (в сравнении с первым вариантом). Также мы снижаем его вложенность за счет использования отдельного http статуса для ошибок бизнес логики (в сравнении со вторым вариантом).

if (status === 200) {
  // Success
} else if (status === 400) {
  if (body.error.code === 1) {
    // some code
  } else if (body.error.code === 2) {
    // some code
  } else {
    // some code
  }
} else {
  // transport erros
}

Мы можем расширять объект ошибки для детализации проблемы, если хотим. С мониторингом все как во втором варианте, дописывать парсинг придется, но и риска “стрельбы” некорректными alert нету. Для документирования можем спокойно использовать Swagger и ApiDoc. При этом сохраняется удобство использования инструментов разработчика, таких как Chrome DevTools, Postman, Talend API.

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

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

P.S. Иногда ошибки любят передавать массивом

{ error: [{ code: 1, msg: 'Не найден пользователь' }] }

Но это актуально в основном в двух случаях:

  • Когда наш API выступает в роли сервиса без фронтенда (нет сайта/приложения). Например, сервис платежей.

  • Когда в API есть url для загрузки какого-нибудь длинного отчета в котором может быть ошибка в каждой строке/колонке. И тогда для пользователя удобнее, чтобы ошибки в приложении сразу показывались все, а не по одной.

В противном случае нет особого смысла закладываться сразу на массив ошибок, потому что базовая валидация данных должна происходить на клиенте, зато код упрощается как на сервере, так и на клиенте. А user-experience хакеров, лезущих напрямую  в наше API,  не должен нас волновать?HTTP

Содержание:

  • Общие сведения
  • Формат ошибок
    • Формат ответа методов API в случае ошибок
      • Структура ответа
      • Описание параметров
  • Описание общих ошибок API

Общие сведения

В документе описан формат ошибок методов API, а также приведен перечень общих ошибок, которые могут возникать при обращении к методам API.

Формат ошибок

Формат ответа методов API в случае ошибок

Структура ответа

  • JSON
  • XML
{  
   "metadata":{  
      "status":400,
      "detail":"abc",
      "generated_at":"2015-06-18 12:37:28"
   },
   "errors":[  
      {  
         "code":281016,
         "title":"ошибка упрощённой отправки",
         "detail":"контрагент с минимальным набором данных не может быть отправителем по заказу",
         "link":"https://dev.dellin.ru/api/ordering/request/#error_281016",
         "fields":["receiver"]
      },
      {  
         "code":281017,
         "title":"Недопустимое значение параметра",
         "detail":"Данный параметр может содержать только значения из списка доступных значений",
         "link":"https://dev.dellin.ru/api/ordering/request/#error_281017",
         "fields":["requester"],
         "validValues":[1, 2, 3]
      },
      {  
         "code":117004,
         "title":"значение не найдено в справочнике",
         "detail":"необходимо выбрать значение из соответствующего справочника",
         "link":"https://dev.dellin.ru/calculation/pickup/#error_117004",
         "fields":["requester"],
         "badValues":["0xa77fcf6a449164ed490133777a68bd00"]
      }
   ]
}
<response>
   <metadata>
      <status>400</status>
      <detail>abc</detail>
      <generated_at>2015-06-18 12:37:28</generated_at>
   </metadata>
   <errors>
      <code>281016</code>
      <title>ошибка упрощённой отправки</title>
      <detail>контрагент с минимальным набором данных не может быть отправителем по заказу</detail>
      <link>https://dev.dellin.ru/api/ordering/request/#error_281016</link>
      <fields>receiver</fields>
   </errors>
   <errors>
      <code>281017</code>
      <title>Недопустимое значение параметра</title>
      <detail>Данный параметр может содержать только значения из списка доступных значений</detail>
      <link>https://dev.dellin.ru/api/ordering/request/#error_281017</link>
      <fields>requester</fields>
      <validValues>1</validValues>
      <validValues>2</validValues>
      <validValues>3</validValues>
   </errors>
   <errors>
      <code>117004</code>
      <title>значение не найдено в справочнике</title>
      <detail>необходимо выбрать значение из соответствующего справочника</detail>
      <link>https://dev.dellin.ru/calculation/pickup/#error_117004</link>
      <fields>requester</fields>
      <badValues>0xa77fcf6a449164ed490133777a68bd00</badValues>
   </errors>
</response>

Описание параметров

Response
Параметр Тип Описание
metadata object Информация об оформленной заявке
metadata.status integer

Эмуляция http-кода состояния

metadata.detail string Текстовое описание ответа сервера
metadata.generated_at string Дата и время генерации ответа сервера
errors array of Response.Errors Перечень ошибок
Response.Errors
Параметр Тип Описание
code integer Номер ошибки
title string

Краткое описание ошибки

detail string Детальное описание ошибки
link string Ссылка на документацию
fields array of string Список параметров в запросе к методу, вызвавших ошибку
validValues array of string Список доступных значений параметра
badValues array of string Список ошибочных значений, переданных в параметре

Описание общих ошибок API

Номер ошибки http-код Краткое описание ошибки Детальное описание ошибки

100001

415 Некорректный content-type Допустимые значения content-type: application/json (стандарт RFC4627) и text/xml (стандарт RFC3023)

100002

404 Метод не найден Проверьте правильность адреса метода

100003

410 Метод отключен Запрошенный метод более не доступен

100004

403 Отсутствует доступ к методу Доступ к методу предоставляется по требованию. Для получения доступа обратитесь к персональному менеджеру или в техническую поддержку

100005

429 Количество запросов к превышено Превышена допустимая частота запросов. Для увеличения лимита обратитесь к персональному менеджеру или в техническую поддержку

100006

500 Внутренняя ошибка сервера Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

101001

401 Требуется авторизация Не передан API-ключ

101002

401 Требуется авторизация Передан недействительный API-ключ

101003

401 Требуется авторизация Требуется передать параметр sessionID

101004

401 Требуется авторизация Время жизни сессии истекло

101005

401 Требуется авторизация Сессия не найдена или создана с другим API-ключом

101006

401 Требуется авторизация Неверный логин или пароль

101007

401 Требуется авторизация API-ключ заблокирован. Обратитесь в техническую поддержку

101008

401 Ошибка парсинга Запрос не соответствует формату json

101009

401 Ошибка парсинга Запрос не соответствует формату xml

110001

400 Неверный формат параметра Значение, переданное в параметре, не соответствует требуемому формату

110002

400 Ошибка типизации Значение, переданное в параметре, имеет некорректный тип

110003

400 Отсутствует обязательный параметр Отсутствует обязательный параметр

110004

400 Не передан ни один из обязательных параметров В запросе должен присутствовать хотя бы один параметр из совокупности, однако не указано ни одного

110005

400 Допустима передача только одного из параметров Указаны взаимоисключающие параметры, только один из которых может присутствовать в запросе

110006

400 Превышено ограничение на длину списка Количество элементов в списке превышает максимально допустимое

110007

400 Объект не существует Не найден объект с указанным ID. Проверьте правильность переданного значения

110008

400 Недопустимый набор параметров Указанные параметры не должны участвовать в запросе

120001

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

(Причина: Сервис calculateCustomers не отвечает)

120002

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

(Причина: Сервис calculateCustomers вернул неизвестную ошибку)

120101

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

(Причина: Сервис calculateCustomersV2 не отвечает)

120102

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

(Причина: Сервис calculateCustomersV2 вернул неизвестную ошибку)

120201

400 Ошибка в параметрах запроса

Переданы неправильные параметры в запрос

(Причина: Переданы некорректные данные в getOrdersTracker)

120301

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

(Причина: Сервис getPaymentsByOrders не отвечает)

121001

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

121002

500 Внутренняя ошибка сервера

Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

130001

500 Внутренняя ошибка сервера Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

130002

400 Ошибка выполнения запроса Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130003

400 Указан некорректный документ, удостоверяющий личность Проверьте правильность переданных значений

130004

400 Не передан ни один из обязательных параметров

В запросе должен присутствовать хотя бы один параметр из совокупности, однако не указано ни одного

130005

400 Отсутствует обязательный параметр Отсутствует обязательный параметр

130006

400 Значение превышает допустимое Габариты превышают допустимые размеры

130007

400 Неверный формат параметра Значение, переданное в параметре, не соответствует требуемому формату

130008

400

Недопустимое значение параметра Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130009

400 Превышено ограничение на длину значения Превышена максимально допустимая длина значения поля

130010

400 Отсутствует согласие с тарифами и правилами перевозки Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130014

400 Ошибка наложенного платежа Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130015

400 Ошибка оформления услуги Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130017

400 Невозможно оформить заявку на указанное время

130021

400 Услуга недоступна Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130022

400 Указан некорректный адрес Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

130023

400 Выбран недопустимый терминал Выбран недопустимый терминал

130024

400 Превышено ограничение на длину списка Превышено максимальное количество контрагентов в адресной книге (10000). Необходимо удалить часть записей или обратиться в службу поддержки

150001

500 Внутренняя ошибка сервера Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

150002

500 Внутренняя ошибка сервера Попробуйте вызвать метод через некоторое время. При повторении ошибки обратитесь в службу поддержки

180001

400 Указан некорректный документ, удостоверяющий личность Проверьте правильность переданных значений

180002

400 Указан некорректный адрес Указан некорректный адрес

180003

400 Выбран недопустимый терминал Выбранный терминал не может принять груз с указанными ВГХ

180004

400 Услуга недоступна Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180005

400 Значение превышает допустимое Весогабаритные характеристики груза превышают допустимые для приёма на терминалах города

180006

400 Ошибка в параметрах запроса Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180007

400 Недопустимое значение параметра Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180008

400 Ошибка упрощенной отправки Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180009

400 Ошибка оформления услуги Доставка в день заказа Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180010

400 Ошибка оформления услуги Доставка в точное время Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180011

400 Указан некорректный период работы Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180012

400 Выбранная дата недоступна Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180013

400 Ошибка параметров оплаты Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180014

400 Ошибка наложенного платежа Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180015

400 Ошибка оформления услуги Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180016

400 Ошибка при сохранении заявки Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

180017

400 Невозможно оформить заявку на указанное время Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра

Автор оригинала: Justin Albano.

1. введение

REST-это архитектура без состояния, в которой клиенты могут получать доступ к ресурсам на сервере и управлять ими. Как правило, службы REST используют HTTP для объявления набора ресурсов, которыми они управляют, и предоставляют API, который позволяет клиентам получать или изменять состояние этих ресурсов.

В этом уроке мы познакомимся с некоторыми из лучших практик обработки ошибок REST API, включая полезные подходы для предоставления пользователям соответствующей информации, примеры из крупномасштабных веб-сайтов и конкретную реализацию с использованием примера приложения Spring REST.

Дальнейшее чтение:

Обработка ошибок для ОТДЫХА с пружиной

Spring ResponseStatusException

2. Коды состояния HTTP

Когда клиент делает запрос к HTTP — серверу — и сервер успешно получает запрос – сервер должен уведомить клиента, был ли запрос успешно обработан или нет . HTTP выполняет это с помощью пяти категорий кодов состояния:

  • 100-уровневый (информационный) — Сервер подтверждает запрос
  • 200-уровень (Успех) — Сервер выполнил запрос, как и ожидалось
  • 300-уровень (Перенаправление) — Клиенту необходимо выполнить дальнейшие действия для завершения запроса
  • 400-level (Ошибка клиента) — Клиент отправил неверный запрос
  • 500-level (Server error) — Серверу не удалось выполнить допустимый запрос из-за ошибки с сервером

Основываясь на коде ответа, клиент может предположить результат конкретного запроса.

3. Обработка Ошибок

Первым шагом в обработке ошибок является предоставление клиенту правильного кода состояния. Кроме того, нам может потребоваться предоставить дополнительную информацию в теле ответа.

3.1. Основные Ответы

Самый простой способ обработки ошибок-это ответить соответствующим кодом состояния .

Некоторые распространенные коды ответов включают в себя:

  • 400 Плохой запрос — Клиент отправил недопустимый запрос — например, отсутствует требуемое тело запроса или параметр
  • 401 Неавторизованный — Клиенту не удалось пройти аутентификацию на сервере
  • 403 Forbidden — Клиент аутентифицирован, но не имеет разрешения на доступ к запрошенному ресурсу
  • 404 Не найден — Запрошенный ресурс не существует
  • 412 Ошибка предварительного условия — одно или несколько условий в полях заголовка запроса оцениваются как ложные.
  • 500 Внутренняя ошибка сервера — На сервере произошла общая ошибка
  • 503 Услуга Недоступна — Запрошенная услуга недоступна

Будучи базовыми, эти коды позволяют клиенту понять широкий характер возникшей ошибки. Например, мы знаем, если получаем ошибку 403, что у нас нет разрешений на доступ к запрошенному ресурсу.

Во многих случаях, однако, мы должны предоставить дополнительные детали в наших ответах.

500 ошибок сигнализируют о том, что при обработке запроса на сервере возникли некоторые проблемы или исключения. Как правило, эта внутренняя ошибка не является делом нашего клиента.

Следовательно, чтобы свести к минимуму такого рода ответы клиенту, мы должны усердно пытаться обрабатывать или улавливать внутренние ошибки и отвечать другими соответствующими кодами состояния, где это возможно . Например, если исключение возникает из-за того, что запрошенный ресурс не существует, мы должны выставить это как ошибку 404, а не 500.

Это не означает, что 500 никогда не должны быть возвращены, только то, что он должен использоваться для непредвиденных условий – таких как отключение службы – которые мешают серверу выполнить запрос.

3.2. Ответы На Весенние ошибки По Умолчанию

Эти принципы настолько распространены, что Spring кодифицировала их в своем механизме обработки ошибок по умолчанию .

Чтобы продемонстрировать это, предположим, что у нас есть простое приложение Spring REST , которое управляет книгами, с конечной точкой для извлечения книги по ее идентификатору:

curl -X GET -H "Accept: application/json" http://localhost:8082/spring-rest/api/book/1

Если нет книги с идентификатором 1, мы ожидаем, что наш контроллер выдаст исключение BookNotFoundException . Выполняя GET на этой конечной точке, мы видим, что это исключение было выброшено, и тело ответа:

{
    "timestamp":"2019-09-16T22:14:45.624+0000",
    "status":500,
    "error":"Internal Server Error",
    "message":"No message available",
    "path":"/api/book/1"
}

Обратите внимание, что этот обработчик ошибок по умолчанию включает метку времени возникновения ошибки, код состояния HTTP, заголовок (поле error ), сообщение (по умолчанию пустое) и URL-адрес, по которому произошла ошибка.

Эти поля предоставляют клиенту или разработчику информацию, помогающую устранить проблему , а также составляют несколько полей, составляющих стандартные механизмы обработки ошибок.

Кроме того, обратите внимание, что Spring автоматически возвращает код состояния HTTP 500 при вызове нашего BookNotFoundException . Хотя некоторые API будут возвращать код состояния 500 или другие общие коды, как мы увидим с API Facebook и Twitter — для всех ошибок ради простоты лучше всего использовать наиболее конкретный код ошибки, когда это возможно .

В нашем примере мы можем добавить @ControllerAdvice так, чтобы при возникновении BookNotFoundException наш API возвращал статус 404 для обозначения Not Found вместо 500 Internal Server Error .

3.3. Более Подробные Ответы

Как видно из приведенного выше примера Spring, иногда кода состояния недостаточно, чтобы показать специфику ошибки. При необходимости мы можем использовать тело ответа, чтобы предоставить клиенту дополнительную информацию. При предоставлении подробных ответов мы должны включать:

  • Error — Уникальный идентификатор ошибки
  • Сообщение — Краткое читаемое человеком сообщение
  • Детализация — более подробное объяснение ошибки

Например, если клиент отправляет запрос с неверными учетными данными, мы можем отправить ответ 401 с телом:

{
    "error": "auth-0001",
    "message": "Incorrect username and password",
    "detail": "Ensure that the username and password included in the request are correct"
}

Поле error не должно совпадать с кодом ответа . Вместо этого это должен быть код ошибки, уникальный для нашего приложения. Как правило, нет никакого соглашения для поля error , ожидайте, что оно будет уникальным.

Обычно это поле содержит только буквенно-цифровые символы и соединительные символы, такие как тире или подчеркивание. Например, 0001 , auth-0001 и incorrect-user-pass являются каноническими примерами кодов ошибок.

Часть тела message обычно считается презентабельной на пользовательских интерфейсах. Поэтому мы должны перевести это название, если мы поддерживаем интернационализацию . Таким образом, если клиент отправляет запрос с заголовком Accept-Language , соответствующим французскому языку, значение title должно быть переведено на французский.

Часть detail предназначена для использования разработчиками клиентов , а не конечным пользователем , поэтому перевод не требуется.

Кроме того, мы также можем предоставить URL — адрес — например, поле help , по которому клиенты могут перейти для получения дополнительной информации:

{
    "error": "auth-0001",
    "message": "Incorrect username and password",
    "detail": "Ensure that the username and password included in the request are correct",
    "help": "https://example.com/help/error/auth-0001"
}

Иногда мы можем захотеть сообщить более чем об одной ошибке для запроса . В этом случае мы должны вернуть ошибки в список:

{
    "errors": [
        {
            "error": "auth-0001",
            "message": "Incorrect username and password",
            "detail": "Ensure that the username and password included in the request are correct",
            "help": "https://example.com/help/error/auth-0001"
        },
        ...
    ]
}

И когда возникает единственная ошибка, мы отвечаем списком, содержащим один элемент. Обратите внимание, что ответ с несколькими ошибками может быть слишком сложным для простых приложений. Во многих случаях достаточно ответить на первую или самую значительную ошибку.

3.4. Стандартизированные Органы реагирования

В то время как большинство API REST следуют аналогичным соглашениям, специфика обычно варьируется, включая имена полей и информацию, включенную в тело ответа. Эти различия затрудняют единообразную обработку ошибок библиотеками и фреймворками.

Стремясь стандартизировать обработку ошибок REST API, |/IETF разработала RFC 7807 , который создает обобщенную схему обработки ошибок .

Эта схема состоит из пяти частей:

  1. тип — Идентификатор URI, который классифицирует ошибку
  2. заголовок — Краткое, читаемое человеком сообщение об ошибке
  3. status — Код ответа HTTP (необязательно)
  4. подробно — Читаемое человеком объяснение ошибки
  5. экземпляр — URI, идентифицирующий конкретное возникновение ошибки

Вместо того чтобы использовать наше пользовательское тело ответа на ошибку, мы можем преобразовать ваше тело в:

{
    "type": "/errors/incorrect-user-pass",
    "title": "Incorrect username or password.",
    "status": 401,
    "detail": "Authentication failed due to incorrect username or password.",
    "instance": "/login/log/abc123"
}

Обратите внимание, что поле type классифицирует тип ошибки, в то время как instance идентифицирует конкретное возникновение ошибки аналогично классам и объектам соответственно.

Используя URI, клиенты могут следовать этим путям, чтобы найти дополнительную информацию об ошибке таким же образом, как ссылки HATEOAS могут использоваться для навигации по REST API.

Придерживаться RFC 7807 необязательно, но выгодно, если требуется однородность.

4. Примеры

Описанные выше методы являются общими для некоторых наиболее популярных API REST. В то время как конкретные имена полей или форматов могут варьироваться между сайтами, общие шаблоны почти универсальны .

4.1. Твиттер

Например, давайте отправим запрос GET без предоставления необходимых аутентификационных данных:

curl -X GET https://api.twitter.com/1.1/statuses/update.json?include_entities=true

API Twitter отвечает ошибкой со следующим телом:

{
    "errors": [
        {
            "code":215,
            "message":"Bad Authentication data."
        }
    ]
}

Этот ответ включает в себя список, содержащий одну ошибку, с ее кодом ошибки и сообщением. В случае Twitter нет подробного сообщения, и общая ошибка — а не более конкретная ошибка 401 — используется для обозначения того, что аутентификация не удалась.

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

4.2. Facebook

Подобно Twitter, Facebook Graph REST API также включает подробную информацию в свои ответы.

Например, давайте выполним POST-запрос для аутентификации с помощью API Facebook Graph:

curl -X GET https://graph.facebook.com/oauth/access_token?client_id=foo&client_secret=bar&grant_type=baz

Мы получаем следующую ошибку:

{
    "error": {
        "message": "Missing redirect_uri parameter.",
        "type": "OAuthException",
        "code": 191,
        "fbtrace_id": "AWswcVwbcqfgrSgjG80MtqJ"
    }
}

Как и Twitter, Facebook также использует общую ошибку — а не более конкретную ошибку 400-го уровня — для обозначения сбоя. В дополнение к сообщению и числовому коду Facebook также включает в себя поле type , которое классифицирует ошибку, и идентификатор трассировки ( fbtrace_id ), который действует как внутренний идентификатор поддержки .

5. Заключение

В этой статье мы рассмотрели некоторые из лучших практик обработки ошибок REST API, в том числе:

  • Предоставление конкретных кодов состояния
  • Включение дополнительной информации в органы реагирования
  • Единообразная обработка исключений

Хотя детали обработки ошибок будут варьироваться в зависимости от приложения, эти общие принципы применимы почти ко всем API REST и должны соблюдаться, когда это возможно .

Это не только позволяет клиентам последовательно обрабатывать ошибки, но и упрощает код, который мы создаем при реализации REST API.

Код, на который ссылается эта статья, доступен на GitHub .

  • Ошибка api ms win eventing classicprovider l1 1 0 dll
  • Ошибка api ms win crt runtime l1 1 0 dll скачать
  • Ошибка api ms win crt runtime l1 1 0 dll решение проблемы виндовс 7
  • Ошибка api ms win crt runtime l1 1 0 dll как исправить windows
  • Ошибка api ms win crt convert l1 1 0 dll решение проблемы