Содержание:
- Общие сведения
- Формат ошибок
- Формат ответа методов API в случае ошибок
- Структура ответа
- Описание параметров
- Формат ответа методов 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 | Невозможно оформить заявку на указанное время | Детальное описание ошибки содержит уточняющую информацию. Текст варьируется в зависимости от проверяемого параметра |
Some Background
REST APIs use the Status-Line part of an HTTP response message to inform clients of their request’s overarching result.
RFC 2616 defines the Status-Line syntax as shown below:
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
A great amount of applications are using Restful APIs that are based on the HTTP protocol for connecting their clients. In all the calls, the server and the endpoint at the client both return a call status to the client which can be in the form of:
- The success of API call.
- Failure of API call.
In both the cases, it is necessary to let the client know so that they can proceed to the next step. In the case of a successful API call they can proceed to the next call or whatever their intent was in the first place but in the case of latter they will be forced to modify their call so that the failed call can be recovered.
RestCase
To enable the best user experience for your customer, it is necessary on the part of the developers to make excellent error messages that can help their client to know what they want to do with the information they get. An excellent error message is precise and lets the user know about the nature of the error so that they can figure their way out of it.
A good error message also allows the developers to get their way out of the failed call.
Next step is to know what error messages to integrate into your framework so that the clients on the end point and the developers at the server are constantly made aware of the situation which they are in. in order to do so, the rule of thumb is to keep the error messages to a minimum and only incorporate those error messages which are helpful.
HTTP defines over 40 standard status codes that can be used to convey the results of a client’s request. The status codes are divided into the five categories presented here:
- 1xx: Informational — Communicates transfer protocol-level information
- 2xx: Success -Indicates that the client’s request was accepted successfully.
- 3xx: Redirection — Indicates that the client must take some additional action in order to complete their request.
- 4xx: Client Error — This category of error status codes points the finger at clients.
- 5xx: Server Error — The server takes responsibility for these error status codes.
If you would ask me 5 years ago about HTTP Status codes I would guess that the talk is about web sites, status 404 meaning that some page was not found and etc. But today when someone asks me about HTTP Status codes, it is 99.9% refers to REST API web services development. I have lots of experience in both areas (Website development, REST API web services development) and it is sometimes hard to come to a conclusion about what and how use the errors in REST APIs.
There are some cases where this status code is always returned, even if there was an error that occurred. Some believe that returning status codes other than 200 is not good as the client did reach your REST API and got response.
Proper use of the status codes will help with your REST API management and REST API workflow management.
If for example the user asked for “account” and that account was not found there are 2 options to use for returning an error to the user:
-
Return 200 OK Status and in the body return a json containing explanation that the account was not found.
-
Return 404 not found status.
The first solution opens up a question whether the user should work a bit harder to parse the json received and to see whether that json contains error or not. -
There is also a third solution: Return 400 Error — Client Error. I will explain a bit later why this is my favorite solution.
It is understandable that for the user it is easier to check the status code of 404 without any parsing work to do.
I my opinion this solution is actually miss-use of the HTTP protocol
We did reach the REST API, we did got response from the REST API, what happens if the users misspells the URL of the REST API – he will get the 404 status but that is returned not by the REST API itself.
I think that these solutions should be interesting to explore and to see the benefits of one versus the other.
There is also one more solution that is basically my favorite – this one is a combination of the first two solutions, he is also gives better Restful API services automatic testing support because only several status codes are returned, I will try to explain about it.
Error handling Overview
Error responses should include a common HTTP status code, message for the developer, message for the end-user (when appropriate), internal error code (corresponding to some specific internally determined ID), links where developers can find more info. For example:
‘{ «status» : 400,
«developerMessage» : «Verbose, plain language description of the problem. Provide developers suggestions about how to solve their problems here»,
«userMessage» : «This is a message that can be passed along to end-users, if needed.»,
«errorCode» : «444444»,
«moreInfo» : «http://www.example.gov/developer/path/to/help/for/444444,
http://tests.org/node/444444»,
}’
How to think about errors in a pragmatic way with REST?
Apigee’s blog post that talks about this issue compares 3 top API providers.
No matter what happens on a Facebook request, you get back the 200 status code — everything is OK. Many error messages also push down into the HTTP response. Here they also throw an #803 error but with no information about what #803 is or how to react to it.
Twilio
Twilio does a great job aligning errors with HTTP status codes. Like Facebook, they provide a more granular error message but with a link that takes you to the documentation. Community commenting and discussion on the documentation helps to build a body of information and adds context for developers experiencing these errors.
SimpleGeo
Provides error codes but with no additional value in the payload.
Error Handling — Best Practises
First of all: Use HTTP status codes! but don’t overuse them.
Use HTTP status codes and try to map them cleanly to relevant standard-based codes.
There are over 70 HTTP status codes. However, most developers don’t have all 70 memorized. So if you choose status codes that are not very common you will force application developers away from building their apps and over to wikipedia to figure out what you’re trying to tell them.
Therefore, most API providers use a small subset.
For example, the Google GData API uses only 10 status codes, Netflix uses 9, and Digg, only 8.
How many status codes should you use for your API?
When you boil it down, there are really only 3 outcomes in the interaction between an app and an API:
- Everything worked
- The application did something wrong
- The API did something wrong
Start by using the following 3 codes. If you need more, add them. But you shouldn’t go beyond 8.
- 200 — OK
- 400 — Bad Request
- 500 — Internal Server Error
Please keep in mind the following rules when using these status codes:
200 (OK) must not be used to communicate errors in the response body
Always make proper use of the HTTP response status codes as specified by the rules in this section. In particular, a REST API must not be compromised in an effort to accommodate less sophisticated HTTP clients.
400 (Bad Request) may be used to indicate nonspecific failure
400 is the generic client-side error status, used when no other 4xx error code is appropriate. For errors in the 4xx category, the response body may contain a document describing the client’s error (unless the request method was HEAD).
500 (Internal Server Error) should be used to indicate API malfunction 500 is the generic REST API error response.
Most web frameworks automatically respond with this response status code whenever they execute some request handler code that raises an exception. A 500 error is never the client’s fault and therefore it is reasonable for the client to retry the exact same request that triggered this response, and hope to get a different response.
If you’re not comfortable reducing all your error conditions to these 3, try adding some more but do not go beyond 8:
- 401 — Unauthorized
- 403 — Forbidden
- 404 — Not Found
Please keep in mind the following rules when using these status codes:
A 401 error response indicates that the client tried to operate on a protected resource without providing the proper authorization. It may have provided the wrong credentials or none at all.
403 (Forbidden) should be used to forbid access regardless of authorization state
A 403 error response indicates that the client’s request is formed correctly, but the REST API refuses to honor it. A 403 response is not a case of insufficient client credentials; that would be 401 (“Unauthorized”). REST APIs use 403 to enforce application-level permissions. For example, a client may be authorized to interact with some, but not all of a REST API’s resources. If the client attempts a resource interaction that is outside of its permitted scope, the REST API should respond with 403.
404 (Not Found) must be used when a client’s URI cannot be mapped to a resource
The 404 error status code indicates that the REST API can’t map the client’s URI to a resource.
RestCase
Conclusion
I believe that the best solution to handle errors in a REST API web services is the third option, in short:
Use three simple, common response codes indicating (1) success, (2) failure due to client-side problem, (3) failure due to server-side problem:
- 200 — OK
- 400 — Bad Request (Client Error) — A json with error more details should return to the client.
- 401 — Unauthorized
- 500 — Internal Server Error — A json with an error should return to the client only when there is no security risk by doing that.
I think that this solution can also ease the client to handle only these 4 status codes and when getting either 400 or 500 code he should take the response message and parse it in order to see what is the problem exactly and on the other hand the REST API service is simple enough.
The decision of choosing which error messages to incorporate and which to leave is based on sheer insight and intuition. For example: if an app and API only has three outcomes which are; everything worked, the application did not work properly and API did not respond properly then you are only concerned with three error codes. By putting in unnecessary codes, you will only distract the users and force them to consult Google, Wikipedia and other websites.
Most important thing in the case of an error code is that it should be descriptive and it should offer two outputs:
- A plain descriptive sentence explaining the situation in the most precise manner.
- An ‘if-then’ situation where the user knows what to do with the error message once it is returned in an API call.
The error message returned in the result of the API call should be very descriptive and verbal. A code is preferred by the client who is well versed in the programming and web language but in the case of most clients they find it hard to get the code.
As I stated before, 404 is a bit problematic status when talking about Restful APIs. Does this status means that the resource was not found? or that there is not mapping to the requested resource? Everyone can decide what to use and where
Table of Contents
- 1. Using http:// instead of https://
- 2. Outdated Caching
- 3. Unexpected error codes
- 5. Sending invalid authorization credentials
- 6. Not specifying Content-Type or Accept header
- 7. APIs returning invalid content type when there is an error
- 8. Failure in team communication
An Application Programming Interface (API) is a software interface that serves as a medium to connect computers and computer programs. APIs have become increasingly valuable that they generate a large portion of many companies’ revenue, including companies such as Google, Amazon, and Salesforce. Today, APIs have adopted useful features that have only added to their value – for example, modern APIs adhere to developer-friendly standards (such as HTTP), and have its own software development lifecycle (SDLC) for its design, build, and version.
Creating an API can be quick and straightforward, however creating one that is secure takes more work and precision. API developers are only human and therefore mistakes can happen, which can ultimately affect the user experience. The following are a few common API errors that may occur:
1. Using http:// instead of https://
Although sometimes API supports both HTTP and HTTPS, missing a single “s” can lead the developer to errors. For example, some APIs redirect HTTP traffic to their HTTPS counterpart, but not all frameworks will be configured to follow a 302 status code. APIs may also stop supporting HTTP, and while good API providers would let users know beforehand, it’s important to stay up-to-date with any changes.
2. Outdated Caching
Caching is essential to the internet and the user experience. By saving data into a public file, users can access the same resources time and time again without overloading the server. Caching is generally a great practice, but improper implementation can be a hindrance and nuisance.
For example, say there is an eCommerce API system that is setup to cache on a frequent basis, in order to update stock and reduce server load during busy cycles. If the API is having a major sale, a larger volume of items would be added to the listing endpoint. However, what becomes problematic is how the data is presented while the listing endpoint is being cached. Customers can see new data if the data is being presented in live form via a dynamic web front, but the poorly implemented caching could lead to a clickable item, a picture, and even a description, all of which would lead to a 404 page when clicked. This is simply because the resolution for that endpoint has not been cached yet.
In this instance, it is important for the developer to test the API as if they are the consumer. This will allow them to approach the code with more caution and attention in order to enhance the user experience and minimize any caching mistakes.
3. Unexpected error codes
API error messages point developers in the right direction whenever there are inconsistencies in the code. However, sometimes unexpected error codes arise and lack sufficient information of what went wrong, leaving the developer scrambling to figure it out themselves.
It is important for API providers to streamline the development process, as exemplified by Twilio, a communications platform. Twilio implements provide links in error messages to point the developer in the right direction to troubleshoot any mistake that may have been made in the code. By maintaining concision and providing more useful information for the developer, any mistake can be quickly addressed.
4. Using the wrong HTTP method
It is very common for developers to use the wrong HTTP method. Oftentimes this can be blamed on poor documentation, but tools can also lead to obstacles if the developer is not attentive. For example, in the situation when a developer wants to create a GET request with a request-body, it is best to make a curl request using the -d option and not use the `-XGET`
flag, which will automatically default to POST and include the `Content-Type: application/x-www-form-urlencoded`
header.
Other times, we might fall into past assumptions and use an incorrect method. For example, the Runscope API uses POST when creating new resources such as test steps or environments, and PUT when modifying them. But Stripe’s API uses POST methods when creating and updating objects.
No matter which approach the developer chooses, it is important to be consistent throughout the API and make sure to have correct and up-to-date documents, so that the users don’t run into this error.
If a request is failing, it is important for the developer to ensure they are using the correct word in their code. For example, APIs that implement OAuth 2 usually require the developer to include an `Authorization` header for each request. However it is common to confuse that with `Authentication`.
It’s also important when using HTTP Basic authentication to pay close attention to the syntax and grammar of the header value. The form is the follows:
Authorization: Basic base64_encode(username:password)
Common mistakes include forgetting the ‘Basic ‘ (note the space before the inverted comma) prefix, not encoding the username and password, or forgetting the colon between them. If an API provider only requires a username without a password (like Stripe, where the API key is the username), the colon after the username is needed, even if there’s no password.
6. Not specifying Content-Type or Accept header
Accept and Content-Type headers negotiate the type of information that will be sent or received between a client and server. Some APIs will accept requests that don’t contain any of those headers and just default to a common format.
However, other APIs might return a 403 error if you’re not explicit about the Accept header value, and will require you to include those headers on requests. This alerts the server as to what information the client is sending, and also what format should be expected to be received.
7. APIs returning invalid content type when there is an error
For API providers, some frameworks and web servers default to HTML. So if a developer is creating an API that has no business returning HTML, it is important to check the default’s error response.
Another aspect to be vigilant about is the routing mesh or load balancer that sits in front of your API. For example, if there is an nginx instance fronting your API and it encounters a request timeout or other error, it may return an HTML error before your API instances even have a chance to receive information about what is occurring.
8. Failure in team communication
In any company, failing to communicate between teams can lead to a cascade of errors and damage control. For example, if the development team does not notify the support team about a type change, the support team would then disperse faulty information and consequently harm the user experience. Likewise, if the UX team does not communicate an interface change to the development team, it could lead to a break in the website’s functionality and the API would be largely inaccessible.
The solution to this situation is simple – communication and team effort. When a plan is set up during the blueprinting stage, it is best to adhere to it and notify the appropriate teams about every revision that is made.
These are some of the most common mistakes that may occur in APIs. They can go unnoticed and lead to more time spent on troubleshooting and debugging. But with the help of the above pointers, combined with a higher level of awareness and attention to detail, these errors can be avoided.
Things don’t always go well when making your first API call, especially if you’re a beginner and it’s your first time integrating an API into another system. Often documentation is lacking in terms of api error status codes, since it’s easier to anticipate things going right, rather than things going wrong.
HTTP status codes can give you an idea of what was going on when you made your API call. The standardized status codes go from 100 to 511, and all have different meanings, but only the status codes from 400 to 511 reflect an error response. If you’re using Moesif, see a summary of the most likely API error status using this handy table.
Let’s look at the 10 most common HTTP status codes that indicate an error response, either on the client or the server-side.
Client-Side Status Codes
The 4XX group of status codes is usually related to client-side errors, but changes to the API can also cause them. Here are the 5 most common client-side status error codes and how to solve for them:
404 Not Found
This is by far the most common HTTP status code you can get. It indicates that the URL you used in your request doesn’t exist on the API server, or origin server. While this is a 4XX error, which usually means something on the client-side is wrong, this can also indicate a server problem. Sometimes API URL paths change after a version update, but sometimes they change because something on the server went wrong.
The best course of action is to check if you have a typo in your client code before checking if the API has issues.
This status code means you haven’t yet authenticated against the API. The API doesn’t know who you are and it won’t serve you.
For most APIs you need to sign up and get an API key. This key is then used inside an HTTP header field when you send a request, telling the API who you are.
This http status code is similar to the less common 407 Proxy Authentication Required, which means you haven’t authenticated with the proxy.
403 Forbidden
The forbidden status indicates that you don’t have permission to request that URL. You’re authenticated, but the user or role you’re authenticated for isn’t permitted to make the API request.
This also occurs when you have an authentication issue, like when using the wrong API key or trying to access features your subscription plan doesn’t allow for.
400 Bad Request
The 400 Bad Request error message is one of the most generic HTTP status codes. It implies that you did not correctly format your API request. If no additional error information is given in the response body, you have to check the docs. You could be missing a query, a field in the request body, or a header field could be wrong. It could also be that some of your request data might have incorrect syntax.
This is different from the 422 Unprocessable Entity error message, which appears when your request is correctly formatted, but cannot be processed.
429 Too Many Requests
Most API subscription plans have limits — the cheaper the plan, the fewer requests per second are allowed for your API key.
If you’re sending too many requests in a short amount of time, consider throttling them in your client. This response can also indicate that you hit a daily, weekly, or monthly limit on your account. Without implementing API analytics, it’s possible to reach these limits without receiving a push notification or email alert.
Sometimes an API sounds like a right fit until you see the limits, and suddenly it doesn’t work for your use case anymore. Check what’s part of your API subscription before integrating, otherwise you may run into problems weeks or months after integrating the API.
Server-Side Status Codes
The 5XX group of status codes usually return in response to a server error, but an invalid API call that should respond with a 4XX can also return a 5XX error if not caught correctly on the server. Here are the 5 most common errors and how to fix them:
500 Internal Server Error
This HTTP status code can mean anything really, but it usually indicates the API server crashed. It could have been caused by something related to your API call.
Double-check the docs to make sure you did everything right: query fields, body fields, headers, and format.
If that didn’t fix the problem, it might also have been related to an API update that introduced buggy code, or data the API loaded from an upstream service. In that case, your only cause of action is contacting the API’s support.
502 Bad Gateway
This response tells you that the server you were calling wasn’t the actual API server, but a gateway or proxy. The proxy server tries to call the API server in your name. This error response also indicates that the API server didn’t answer. This could be related to a network problem, or simply because the API server crashed, or was down for maintenance.
A “bad gateway” error is usually temporary and should be solved by the API provider, but you have to contact support if it persists.
503 Service Unavailable
The 503 Service Unavailable Status indicates a server error. Too many API requests were sent and now the API can’t handle any more of them. This problem solves itself when clients send fewer future requests, but it could also mean that the API provider didn’t plan enough resources for all of its customers.
If it fits your use case, you can make your client more resilient to this error by waiting to send another request. But if the error code keeps showing up, you have to contact the API provider.
504 Gateway Timed Out
Like the 502 Bad Gateway status, this response code tells you that the server you were calling is a proxy for the real API server. This time, the problem is the API server’s slow response.
This could be related to high network latency between the proxy and the API server. It could also mean that the API server takes too long to process your request.
To solve this problem, check if your request’s content could be related to that timeout. If you are requesting too much data or a calculation that takes too long, you should try and reduce it.
If you think your request is reasonable and the status doesn’t go away, contact support.
501 Not Implemented
The 501 Not Implemented status code is related to the HTTP method you used to request an URL. You can try a different HTTP method to make the request.
Usually, an HTTP request with an inappropriate method simply results in a 404 not found status. A not-implemented status implies that the method isn’t implemented “yet.” The API creator can use this status to tell the clients that this method will be available to them in future requests.
Monitoring HTTP Status Codes With Moesif
Moesif provides a rich set of monitoring and notification capabilities, so you can keep abreast of any HTTP status code errors automatically and gain deep insights from your error response trends.
API calls are always tracked with user identity, so it’s easy to locate errors and solve them rapidly.
Summary
Undoubtedly you’ll see many error codes when using APIs, but most have reasonable fixes. Some are related to server errors and some to client-side errors, where often one can cause the other.
Always try to read the docs and API notes thoroughly, so you don’t forget something while integrating. If things are simply broken, contact the API provider.
In some cases, the API provider won’t ever fix an issue for an API consumer. If you’re using a popular API you can also search the web for answers, especially StackOverflow, to find a fix for your error responses. Stay determined, and you’ll see your 200 ok status codes in no time.
Debug And Fix API Issues Quickly With High-cardinality API Logs
Learn More
Kay Ploesser
Software Engineer and Web Enthusiast
This chapter provides an overview of the error model for Google APIs. It also
provides general guidance to developers on how to properly generate and
handle errors.
Google APIs use a simple protocol-agnostic error model, which allows us to
offer a consistent experience across different APIs, different API protocols
(such as gRPC or HTTP), and different error contexts (such as asynchronous,
batch, or workflow errors).
Error Model
The error model for Google APIs is logically defined by
google.rpc.Status
,
an instance of which is returned to the client when an API error occurs. The
following code snippet shows the overall design of the error model:
package google.rpc;
// The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs.
message Status {
// A simple error code that can be easily handled by the client. The
// actual error code is defined by `google.rpc.Code`.
int32 code = 1;
// A developer-facing human-readable error message in English. It should
// both explain the error and offer an actionable resolution to it.
string message = 2;
// Additional error information that the client code can use to handle
// the error, such as retry info or a help link.
repeated google.protobuf.Any details = 3;
}
Because most Google APIs use resource-oriented API design, the error handling
follows the same design principle by using a small set of standard errors with a
large number of resources. For example, instead of defining different kinds of
«not found» errors, the server uses one standard google.rpc.Code.NOT_FOUND
error code and tells the client which specific resource was not found. The
smaller error space reduces the complexity of documentation, affords better
idiomatic mappings in client libraries, and reduces client logic complexity
while not restricting the inclusion of actionable information.
Error Codes
Google APIs must use the canonical error codes defined by
google.rpc.Code
.
Individual APIs must avoid defining additional error codes, since
developers are very unlikely to write logic to handle a large number of error
codes. For reference, handling an average of three error codes per API call
would mean most application logic would just be for error handling, which would
not be a good developer experience.
Error Messages
The error message should help users understand and resolve the API error
easily and quickly. In general, consider the following guidelines when writing
error messages:
- Do not assume the user is an expert user of your API. Users could be client
developers, operations people, IT staff, or end-users of apps. - Do not assume the user knows anything about your service implementation or
is familiar with the context of the errors (such as log analysis). - When possible, error messages should be constructed such that a technical
user (but not necessarily a developer of your API) can respond to the error
and correct it. - Keep the error message brief. If needed, provide a link where a confused
reader can ask questions, give feedback, or get more information that
doesn’t cleanly fit in an error message. Otherwise, use the details field to
expand.
Error Details
Google APIs define a set of standard error payloads for error details, which you
can find in
google/rpc/error_details.proto.
These cover the most common needs for API errors, such as quota failure and
invalid parameters. Like error codes, developers should use these standard
payloads whenever possible.
Additional error detail types should only be introduced if they can assist
application code to handle the errors. If the error information can only be
handled by humans, rely on the error message content and let developers handle
it manually rather than introducing additional error detail types.
Here are some example error_details
payloads:
ErrorInfo
: Provides structured error information that is both stable
and extensible.RetryInfo
: Describes when clients can retry a failed request, may be
returned onCode.UNAVAILABLE
orCode.ABORTED
QuotaFailure
: Describes how a quota check failed, may be returned on
Code.RESOURCE_EXHAUSTED
BadRequest
: Describes violations in a client request, may be returned on
Code.INVALID_ARGUMENT
Error Info
ErrorInfo
is a special kind of error payload. It provides stable and
extensible error information that both humans and applications can depend on.
Each ErrorInfo
has three pieces of information: an error domain, an error
reason, and a set of error metadata, such as this
example.
For more information, see the
ErrorInfo
definition.
For Google APIs, the primary error domain is googleapis.com
, and the
corresponding error reasons are defined by google.api.ErrorReason
enum.
For more information, see the
google.api.ErrorReason
definition.
Error Localization
The message
field in
google.rpc.Status
is developer-facing and must be in English.
If a user-facing error message is needed, use
google.rpc.LocalizedMessage
as your details field. While the message field in
google.rpc.LocalizedMessage
can be localized, ensure that the message field in
google.rpc.Status
is in English.
By default, the API service should use the authenticated user’s locale or HTTP
Accept-Language
header or the language_code
parameter in the request to
determine the language for the localization.
Error Mapping
Google APIs are accessible in different programming environments. Each
environment typically has its own way of error handling. The following
sections explain how the error model is mapped in commonly used environments.
HTTP Mapping
While proto3 messages have native JSON encoding, Google’s API Platform uses a
different error schema for Google’s JSON HTTP APIs for backward compatibility
reasons.
Schema:
// This message defines the error schema for Google's JSON HTTP APIs.
message Error {
// Deprecated. This message is only used by error format v1.
message ErrorProto {}
// This message has the same semantics as `google.rpc.Status`. It uses HTTP
// status code instead of gRPC status code. It has extra fields `status` and
// `errors` for backward compatibility with [Google API Client
// Libraries](https://developers.google.com/api-client-library).
message Status {
// The HTTP status code that corresponds to `google.rpc.Status.code`.
int32 code = 1;
// This corresponds to `google.rpc.Status.message`.
string message = 2;
// Deprecated. This field is only used by error format v1.
repeated ErrorProto errors = 3;
// This is the enum version for `google.rpc.Status.code`.
google.rpc.Code status = 4;
// This corresponds to `google.rpc.Status.details`.
repeated google.protobuf.Any details = 5;
}
// The actual error payload. The nested message structure is for backward
// compatibility with [Google API Client
// Libraries](https://developers.google.com/api-client-library). It also
// makes the error more readable to developers.
Status error = 1;
}
Example (link):
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "translate.googleapis.com"
}
}
]
}
}
gRPC Mapping
Different RPC protocols map the error model differently. For
gRPC, the error model is natively supported by the generated
code and the runtime library in each supported language. You can find out more
in gRPC’s API documentation. For example, see gRPC Java’s
io.grpc.Status
.
Client Library Mapping
Google client libraries may choose to surface errors differently per language to
be consistent with established idioms. For example, the
google-cloud-go
library will return an error that implements the same interface as
google.rpc.Status
,
while
google-cloud-java
will raise an Exception.
Handling Errors
Below is a table containing all of the gRPC error codes defined in
google.rpc.Code
and a short description of their cause. To handle an error, you can check the
description for the returned status code and modify your call accordingly.
HTTP | gRPC | Description |
---|---|---|
200 | OK |
No error. |
400 | INVALID_ARGUMENT |
Client specified an invalid argument. Check error message and error details for more information. |
400 | FAILED_PRECONDITION |
Request can not be executed in the current system state, such as deleting a non-empty directory. |
400 | OUT_OF_RANGE |
Client specified an invalid range. |
401 | UNAUTHENTICATED |
Request not authenticated due to missing, invalid, or expired OAuth token. |
403 | PERMISSION_DENIED |
Client does not have sufficient permission. This can happen because the OAuth token does not have the right scopes, the client doesn’t have permission, or the API has not been enabled. |
404 | NOT_FOUND |
A specified resource is not found. |
409 | ABORTED |
Concurrency conflict, such as read-modify-write conflict. |
409 | ALREADY_EXISTS |
The resource that a client tried to create already exists. |
429 | RESOURCE_EXHAUSTED |
Either out of resource quota or reaching rate limiting. The client should look for google.rpc.QuotaFailure error detail for more information. |
499 | CANCELLED |
Request cancelled by the client. |
500 | DATA_LOSS |
Unrecoverable data loss or data corruption. The client should report the error to the user. |
500 | UNKNOWN |
Unknown server error. Typically a server bug. |
500 | INTERNAL |
Internal server error. Typically a server bug. |
501 | NOT_IMPLEMENTED |
API method not implemented by the server. |
502 | N/A | Network error occurred before reaching the server. Typically a network outage or misconfiguration. |
503 | UNAVAILABLE |
Service unavailable. Typically the server is down. |
504 | DEADLINE_EXCEEDED |
Request deadline exceeded. This will happen only if the caller sets a deadline that is shorter than the method’s default deadline (i.e. requested deadline is not enough for the server to process the request) and the request did not finish within the deadline. |
Retrying Errors
Clients may retry on 503 UNAVAILABLE errors with exponential backoff.
The minimum delay should be 1s unless it is documented otherwise. The default
retry repetition should be once unless it is documented otherwise.
For 429 RESOURCE_EXHAUSTED errors, the client may retry at the higher level
with minimum 30s delay. Such retries are only useful for long running
background jobs.
For all other errors, retry may not be applicable. First ensure your request
is idempotent, and see
google.rpc.RetryInfo
for guidance.
Propagating Errors
If your API service depends on other services, you should not blindly propagate
errors from those services to your clients. When translating errors, we suggest
the following:
- Hide implementation details and confidential information.
- Adjust the party responsible for the error. For example, a server that
receives anINVALID_ARGUMENT
error from another service should propagate
anINTERNAL
to its own caller.
Reproducing Errors
If you cannot resolve errors through analysis of logs and monitoring, you should
try to reproduce the errors with a simple and repeatable test. You can use the
test to collect more information for troubleshooting, which you can provide
when contacting technical support.
We recommend you use curl -v
and
System Parameters to reproduce errors with
Google APIs. Together they can reproduce almost all Google API requests,
and provide you verbose debug information. For more information, see the
respective documentation pages for the API you are calling.
Generating Errors
If you are a server developer, you should generate errors with enough
information to help client developers understand and resolve the problem. At the
same time, you must be aware of the security and privacy of the user data, and
avoid disclosing sensitive information in the error message and error details,
since errors are often logged and may be accessible by others. For example, an
error message like «Client IP address is not on allowlist 128.0.0.0/8» exposes
information about the server-side policy, which may not be accessible to the
user who has access to the logs.
To generate proper errors, you first need to be familiar with google.rpc.Code
to
choose the most suitable error code for each error condition. A server
application may check multiple error conditions in parallel, and return the
first one.
The following table lists each error code and an example of a good error
message.
HTTP | gRPC | Example Error Message |
---|---|---|
400 | INVALID_ARGUMENT |
Request field x.y.z is xxx, expected one of [yyy, zzz]. |
400 | FAILED_PRECONDITION |
Resource xxx is a non-empty directory, so it cannot be deleted. |
400 | OUT_OF_RANGE |
Parameter ‘age’ is out of range [0, 125]. |
401 | UNAUTHENTICATED |
Invalid authentication credentials. |
403 | PERMISSION_DENIED |
Permission ‘xxx’ denied on resource ‘yyy’. |
404 | NOT_FOUND |
Resource ‘xxx’ not found. |
409 | ABORTED |
Couldn’t acquire lock on resource ‘xxx’. |
409 | ALREADY_EXISTS |
Resource ‘xxx’ already exists. |
429 | RESOURCE_EXHAUSTED |
Quota limit ‘xxx’ exceeded. |
499 | CANCELLED |
Request cancelled by the client. |
500 | DATA_LOSS |
See note. |
500 | UNKNOWN |
See note. |
500 | INTERNAL |
See note. |
501 | NOT_IMPLEMENTED |
Method ‘xxx’ not implemented. |
503 | UNAVAILABLE |
See note. |
504 | DEADLINE_EXCEEDED |
See note. |
Error Payloads
The google.rpc
package defines a set of standard error payloads, which are
preferred to custom error payloads. The following table lists each error code
and its matching standard error payload, if applicable. We recommend advanced
applications look for these error payloads in google.rpc.Status
when they
handle errors.
HTTP | gRPC | Recommended Error Detail |
---|---|---|
400 | INVALID_ARGUMENT |
google.rpc.BadRequest |
400 | FAILED_PRECONDITION |
google.rpc.PreconditionFailure |
400 | OUT_OF_RANGE |
google.rpc.BadRequest |
401 | UNAUTHENTICATED |
google.rpc.ErrorInfo |
403 | PERMISSION_DENIED |
google.rpc.ErrorInfo |
404 | NOT_FOUND |
google.rpc.ResourceInfo |
409 | ABORTED |
google.rpc.ErrorInfo |
409 | ALREADY_EXISTS |
google.rpc.ResourceInfo |
429 | RESOURCE_EXHAUSTED |
google.rpc.QuotaFailure |
499 | CANCELLED |
|
500 | DATA_LOSS |
google.rpc.DebugInfo |
500 | UNKNOWN |
google.rpc.DebugInfo |
500 | INTERNAL |
google.rpc.DebugInfo |
501 | NOT_IMPLEMENTED |
|
503 | UNAVAILABLE |
google.rpc.DebugInfo |
504 | DEADLINE_EXCEEDED |
google.rpc.DebugInfo |