I am thinking 412 (Precondition Failed) but there may be a better standard?
asked Jun 16, 2010 at 3:19
2
Status 422 seems most appropiate based on the spec.
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
They state that malformed xml is an example of bad syntax (calling for a 400). A malformed query string seems analogous to this, so 400 doesn’t seem appropriate for a well-formed query-string which is missing a param.
Note: Since the above RFC is about WebDAV there can be a misunderstanding that 422 and some others are only to be used in the context of WebDAV and using them outside of it is «nonstandard». But this only means these status codes were introduced in the context of this RFC. Indeed the wording of these definitions is carefully chosen not to be specific to WebDAV.
David Ongaro
3,3601 gold badge23 silver badges35 bronze badges
answered Apr 25, 2012 at 20:14
KelvinKelvin
19.6k2 gold badges60 silver badges65 bronze badges
18
I’m not sure there’s a set standard, but I would have used 400 Bad Request, which the latest HTTP spec (from 2014) documents as follows:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
answered Jun 16, 2010 at 3:32
Gert GrenanderGert Grenander
16.7k6 gold badges39 silver badges43 bronze badges
12
The WCF API in .NET handles missing parameters by returning an HTTP 404
«Endpoint Not Found» error, when using the webHttpBinding.
The 404 Not Found
can make sense if you consider your web service method name together with its parameter signature. That is, if you expose a web service method LoginUser(string, string)
and you request LoginUser(string)
, the latter is not found.
Basically this would mean that the web service method you are calling, together with the parameter signature you specified, cannot be found.
10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No
indication is given of whether the condition is temporary or
permanent.
The 400 Bad Request
, as Gert suggested, remains a valid response code, but I think it is normally used to indicate lower-level problems. It could easily be interpreted as a malformed HTTP request, maybe missing or invalid HTTP headers, or similar.
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
answered Jun 16, 2010 at 3:55
Daniel VassalloDaniel Vassallo
334k71 gold badges501 silver badges441 bronze badges
7
You can send a 400 Bad Request code. It’s one of the more general-purpose 4xx status codes, so you can use it to mean what you intend: the client is sending a request that’s missing information/parameters that your application requires in order to process it correctly.
answered Jun 16, 2010 at 3:32
BoltClockBoltClock
687k158 gold badges1373 silver badges1349 bronze badges
I Usually go for 422 (Unprocessable entity) if something in the required parameters didn’t match what the API endpoint required (like a too short password) but for a missing parameter i would go for 406 (Unacceptable).
answered Mar 6, 2014 at 9:32
Elad MeidarElad Meidar
7646 silver badges11 bronze badges
3
In one of our API project we decide to set a 409 Status to some request, when we can’t full fill it at 100% because of missing parameter.
HTTP Status Code «409 Conflict» was for us a good try because it’s definition
require to include enough information for the user to recognize the
source of the conflict.
Reference: w3.org/Protocols/
So among other response like 400 or 404 we chose 409 to enforce the need for looking over some notes in the request helpful to set up a new and right request.
Any way our case it was particular because we need to send out some data eve if the request was not completely correct, and we need to enforce the client to look at the message and understand what was wrong in the request.
In general if we have only some missing parameter we go for a 400 and an array of missing parameter. But when we need to send some more information, like a particular case message and we want to be more sure the client will take care of it we send a 409
answered Jan 8, 2015 at 14:06
gabrielemgabrielem
5605 silver badges13 bronze badges
3
For those interested, Spring MVC (3.x at least) returns a 400 in this case, which seems wrong to me.
I tested several Google URLs (accounts.google.com) and removed required parameters, and they generally return a 404 in this case.
I would copy Google.
answered May 19, 2012 at 21:01
RelefantRelefant
89310 silver badges10 bronze badges
5
It could be argued that a 404 Not Found
should be used since the resource specified could not be found.
Luca
9,0335 gold badges45 silver badges59 bronze badges
answered Jan 17, 2012 at 14:44
3
I often use a 403 Forbidden error. The reasoning is that the request was understood, but I’m not going to do as asked (because things are wrong). The response entity explains what is wrong, so if the response is an HTML page, the error messages are in the page. If it’s a JSON or XML response, the error information is in there.
From rfc2616:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.
answered Feb 23, 2012 at 22:36
cdeszaqcdeszaq
30.5k25 gold badges115 silver badges173 bronze badges
5
Just go to the browser settings > Shields > Auto-redirect AMP pages
Disable it and try again …
answered Oct 18, 2022 at 21:18
I am thinking 412 (Precondition Failed) but there may be a better standard?
asked Jun 16, 2010 at 3:19
2
Status 422 seems most appropiate based on the spec.
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
They state that malformed xml is an example of bad syntax (calling for a 400). A malformed query string seems analogous to this, so 400 doesn’t seem appropriate for a well-formed query-string which is missing a param.
Note: Since the above RFC is about WebDAV there can be a misunderstanding that 422 and some others are only to be used in the context of WebDAV and using them outside of it is «nonstandard». But this only means these status codes were introduced in the context of this RFC. Indeed the wording of these definitions is carefully chosen not to be specific to WebDAV.
David Ongaro
3,3601 gold badge23 silver badges35 bronze badges
answered Apr 25, 2012 at 20:14
KelvinKelvin
19.6k2 gold badges60 silver badges65 bronze badges
18
I’m not sure there’s a set standard, but I would have used 400 Bad Request, which the latest HTTP spec (from 2014) documents as follows:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
answered Jun 16, 2010 at 3:32
Gert GrenanderGert Grenander
16.7k6 gold badges39 silver badges43 bronze badges
12
The WCF API in .NET handles missing parameters by returning an HTTP 404
«Endpoint Not Found» error, when using the webHttpBinding.
The 404 Not Found
can make sense if you consider your web service method name together with its parameter signature. That is, if you expose a web service method LoginUser(string, string)
and you request LoginUser(string)
, the latter is not found.
Basically this would mean that the web service method you are calling, together with the parameter signature you specified, cannot be found.
10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No
indication is given of whether the condition is temporary or
permanent.
The 400 Bad Request
, as Gert suggested, remains a valid response code, but I think it is normally used to indicate lower-level problems. It could easily be interpreted as a malformed HTTP request, maybe missing or invalid HTTP headers, or similar.
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
answered Jun 16, 2010 at 3:55
Daniel VassalloDaniel Vassallo
334k71 gold badges501 silver badges441 bronze badges
7
You can send a 400 Bad Request code. It’s one of the more general-purpose 4xx status codes, so you can use it to mean what you intend: the client is sending a request that’s missing information/parameters that your application requires in order to process it correctly.
answered Jun 16, 2010 at 3:32
BoltClockBoltClock
687k158 gold badges1373 silver badges1349 bronze badges
I Usually go for 422 (Unprocessable entity) if something in the required parameters didn’t match what the API endpoint required (like a too short password) but for a missing parameter i would go for 406 (Unacceptable).
answered Mar 6, 2014 at 9:32
Elad MeidarElad Meidar
7646 silver badges11 bronze badges
3
In one of our API project we decide to set a 409 Status to some request, when we can’t full fill it at 100% because of missing parameter.
HTTP Status Code «409 Conflict» was for us a good try because it’s definition
require to include enough information for the user to recognize the
source of the conflict.
Reference: w3.org/Protocols/
So among other response like 400 or 404 we chose 409 to enforce the need for looking over some notes in the request helpful to set up a new and right request.
Any way our case it was particular because we need to send out some data eve if the request was not completely correct, and we need to enforce the client to look at the message and understand what was wrong in the request.
In general if we have only some missing parameter we go for a 400 and an array of missing parameter. But when we need to send some more information, like a particular case message and we want to be more sure the client will take care of it we send a 409
answered Jan 8, 2015 at 14:06
gabrielemgabrielem
5605 silver badges13 bronze badges
3
For those interested, Spring MVC (3.x at least) returns a 400 in this case, which seems wrong to me.
I tested several Google URLs (accounts.google.com) and removed required parameters, and they generally return a 404 in this case.
I would copy Google.
answered May 19, 2012 at 21:01
RelefantRelefant
89310 silver badges10 bronze badges
5
It could be argued that a 404 Not Found
should be used since the resource specified could not be found.
Luca
9,0335 gold badges45 silver badges59 bronze badges
answered Jan 17, 2012 at 14:44
3
I often use a 403 Forbidden error. The reasoning is that the request was understood, but I’m not going to do as asked (because things are wrong). The response entity explains what is wrong, so if the response is an HTML page, the error messages are in the page. If it’s a JSON or XML response, the error information is in there.
From rfc2616:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.
answered Feb 23, 2012 at 22:36
cdeszaqcdeszaq
30.5k25 gold badges115 silver badges173 bronze badges
5
Just go to the browser settings > Shields > Auto-redirect AMP pages
Disable it and try again …
answered Oct 18, 2022 at 21:18
Умные люди придумали коды, по которым можно определить, что произошло с HTTP-запросом. Успешен ли он, произошло ли перенаправление. Или же все закончилось ошибкой. Как раз об ошибках и будем говорить в этой статье. Вкратце расскажу, какие они бывают и с чем связаны.
А еще тут будет парочка забавных (и не очень) пикч и анимаций на тему описанных ошибок. Хоть какое-то развлечение.
Ошибки со стороны клиента (4xx)
Для начала перечислим коды ошибок на стороне клиента. Вина за их появление ложится на плечи обоих участников соединения.
400 Bad Request
Такой ответ от браузера можно получить в том случае, если сервер не смог правильно отреагировать на запрос со стороны пользователя. Часто код 400 возникает при попытке клиента получить доступ к серверу без соблюдения правил оформления синтаксиса протокола передачи гипертекста (HTTP). Повторный запрос не стоит отправлять до тех пор, пока не будет исправлена ошибка (или несколько из них).
401 Unauthorized
Код 401 возникает при попытке клиента получить доступ к серверу, используя неправильные данные для авторизации. По сути, используется, когда пользователь вводит неправильный логин и пароль на ресурсе, где требуется эта информация для входа. Читайте: Как исправить ошибку 401
402 Payment Required
Эта ошибка сообщает клиенту о том, что для успешного выполнения запроса ему необходимо оплатить доступ к серверу. Изначально код 402 должен был стать неким стандартом для цифровой валюты и оплаты контента в сети. Но не срослось. До сих пор нет единого решения по поводу того, как должны выглядеть платежи в сети. Также нет и единого решения по поводу того, как стоит использовать 402.
Все еще считается, что код существует с расчетом на будущее. Сейчас почти не используется и поддерживается не всеми браузерами.
403 Forbidden
Почти то же, что и 401. Сервер снова не разрешает к нему подключиться, хотя с запросом все в порядке. Просто нет доступа. Причем повторная авторизация с другими логином и паролем никак не помогут. Все вопросы к владельцам сервера (но не всегда). Инструкция по устранению ошибки.
Творчество на тему знаменитой киносаги
404 Not Found
Легендарная ошибка, ставшая популярным мемом. 404 оповещает клиента о том, что его запрос ведет в никуда. Код возникает, когда пользователь пытается попасть на страницу, которой не существует. Например, когда случайно ошибается при вводе ссылки и вводит ее с опечаткой. Или же пытается получить доступ к странице, которой на сайте уже нет.
В отличие от других кодов, страницу с 404 частенько кастомизируют, создавая для нее уникальный дизайн. Мало того, что это выглядит симпатичнее, так еще и полезнее для посетителей. Можно прямо на странице с ошибкой разъяснить, что произошло и как дальше действовать.
И таких вариаций тысячи. Каждый пытается добавить в оформление что-то свое.
405 Method Not Allowed
405 сообщает клиенту о том, что метод, используемый при запросе, не разрешен. В качестве примера можно привести попытку со стороны клиента ввести данные в форму с помощью GET, когда она работает только с POST. Ну и в таком же духе.
406 Not Acceptable
Ошибка 406 сообщает о том, что страница передает контент, который не может быть распознан клиентом. Возможно, проблема в методе сжатия или в формате страницы. Иногда сюда же приплетают неправильные настройки кодировки.
Этот код редко используют на практике, так как его появления можно избежать, предоставив пользователю информацию на сайте в том виде, который его браузер способен принять. Посетитель сайта по итогу получит не то, что ожидал, но хотя бы не ошибку.
407 Proxy Authentication Required
Этот код тоже похож на 401. Только на этот раз логин и пароль нужны не для основного сервера, а для прокси, который находится между клиентом и сервером. Обычно в теле ошибки содержится информация о том, как можно правильно пройти авторизацию и получить доступ к ресурсу.
408 Request Timeout
408 говорит нам о том, что сервер пожелал разорвать соединение с клиентом, потому что оно никак не используется. Происходит это в том случае, если сервер буквально устал ждать, пока наладится соединение с ним. Поэтому такую ошибку часто можно лицезреть после очень долгой и безуспешной загрузки какого-нибудь сайта.
Многие серверы не отправляют никаких сообщений, а просто прерывают соединение по той же причине. На запрос уходит больше времени, чем на то полагается.
В Мистере Роботе частенько называли серии в честь ошибок HTTP (весь четвертый сезон в нумерации 4хх). В честь 408, например, назвали восьмую серию четвертого сезона
409 Conflict
Сообщение о конфликте возникает, когда запрос со стороны клиента не соответствует тому, чего ожидает сервер. В качестве примера приводят проблемы при проверки версий, когда пользователь пытается с помощью метода PUT загрузить на сервер новый файл, но там уже имеется более новая версия того же файла. Конфликта версий можно легко избежать, загрузив корректную версию.
410 Gone
Своего рода аналог 404. Разница лишь в том, что 410 намекает на перманентность отсутствия страницы. Так что этот код стоит использовать, когда на 100% уверен, что страница ушла в небытие (ну или с текущего адреса) навсегда. В любом другом случае есть универсальный 404.
411 Length Required
411 оповещает пользователя о том, что сервер не желает принимать запрос со стороны клиента, потому что в нем не определен заголовок Content-Length. Да, это первый код в подборке, который смогут понять только люди, сведущие в настройке серверов. По-простому уложить сущность HTML-заголовков в этот материал не получится.
412 Precondition Failed
Еще один код, сообщающий о том, что сервер отклонил запрос пользователя и не разрешает доступ к выбранному ресурсу. Проблемы возникают при неправильной настройке работы методов, отличающихся от GET и HEAD.
413 Payload Too Large/Request Entity Too Large
Код 413 говорит нам, что запрос, который посылает клиент на сервер, слишком большой. Поэтому сервер отказывается его обрабатывать и разрывает соединение. Обычно это происходит при попытке загрузить на ресурс какой-то файл, превышающий ограничение, выставленное в настройках сервера. Соответственно, решается проблема изменением настроек сервера.
414 URI Too Long
Чем-то этот код похож на предыдущий. Здесь тоже идет речь о превышение лимита. Только теперь это касается не запроса со стороны клиента, а длины URI. То есть ссылки. Выходит, что адрес, используемый клиентом, больше, чем тот, что может обработать сервер. Как-то так.
Такая ошибка иногда выскакивает при попытке взломать ресурс. Сайт так реагирует на слишком частые попытки воспользоваться потенциальными дырами в безопасности.
415 Unsupported Media Type
Ошибка 415 возникает, когда клиент пытается загрузить на сервер данные в неподходящем формате. В таком случае сервер просто отказывается принимать посылаемые файлы и разрывает соединение. Как и в случае с 413.
416 Range Not Satisfiable
Подобный ответ можно ожидать, если клиент запрашивает у сервера определенные данные, но эти данные на сервере не соответствуют запросу. То есть, грубо говоря, вы просите у сервера какой-то набор данных с заранее заданным размером, а в итоге оказывается, что размер этих данных меньше, чем объем, указанный в запросе. Серверу ничего не остается, кроме как послать вас, ведь он не обучен поведению в таких ситуациях.
417 Expectation Failed
Такая ошибка высвечивается, когда ожидания сервера не совпадают с данными в запросе клиента. Сведения об ожиданиях прописываются в заголовке Expect заранее. Так что можно ознакомиться с ними, чтобы выяснить, как решить названную проблему.
418 I’m a teapot
Код 418 можно увидеть, если сервер откажется варить кофе, потому что он чайник. Это первоапрельская шутка. Естественно, 418 не используется нигде всерьез и просто существует как дань памяти программистам-юмористам, придумавшим это в 1998 году.
У Google получился такой симпатичный чайник
421 Misdirected Request
Появляется когда запрос клиента переправляется на сервер, который не может дать на него адекватный ответ. Например, если запрос был отправлен на ресурс, который вообще не настроен обрабатывать запросы извне.
Чтобы исправить проблему, можно попробовать переподключиться к ресурсу заново или попробовать другое соединение.
422 Unprocessable Entity
Код 422 говорит, что сервер вроде бы принял запрос, понял его, все хорошо, но из-за семантических ошибок корректно обработать не смог. Значит, где-то в запросе затаилась логическая ошибка, мешающая корректному взаимодействию клиента и сервера. Надо ее найти и исправить.
423 Locked
Обычно на этот код напарываются, когда запрашиваемый ресурс оказывается под защитой. Используемые клиентом методы блокируются на уровне сервера. Это делается, чтобы обезопасить данные, хранящиеся на защищенной странице. Без логина и пароля выудить информацию с такого сервера не получится.
424 Failed Dependency
424 сообщает о том, что для выполнения запроса со стороны клиента успешно должна завершиться еще одна или несколько параллельных операций. Если какая-то из них «провалится», то «помрет» все соединение сразу, и обработать запрос до конца не получится. Аналогичное происходит, если некорректно был обработан один из предыдущих запросов.
425 Too Early
Появляется в ответ на запрос, который может быть моментально запущен заново. Сервер не рискует и не берется за его обработку, чтобы не подставиться под так называемую «атаку повторного воспроизведения».
426 Upgrade Required
Тут нам прямо сообщают, что сервер не желает с нами общаться, пока мы не перейдем на более современный протокол. Наткнуться на такую ошибку очень тяжело, но в случае появления, скорее всего, будет достаточно установить браузер посвежее.
428 Precondition Required
428 выскакивает, если пользователь отправляет запрос на сервер, но получает некорректные или неактуальные данные. Так ресурс оповещает о необходимости внести в запрос информацию о предварительных условиях обработки данных. Только так он сможет гарантировать получение клиентом нужной информации.
429 Too Many Requests
Здесь все просто. Ошибка появляется, когда клиент отправляет на сервер слишком много запросов в короткий промежуток времени. Очень похоже на поведение взломщиков. По этой причине запрос моментально блокируется.
431 Request Header Fields Too Large
Из названия понятно, что ошибка с кодом 431 появляется из-за того, что в запросе клиента используются слишком длинные заголовки (неважно, один или несколько из них). Исправляется это с помощью сокращения заголовков и повторной отправки запроса. В теле ошибки обычно отображается краткая информация о том, как пользователь может решить эту проблему самостоятельно.
444 No Response
Этот код вам вряд ли удастся увидеть. Он отображается в лог-файлах, чтобы подтвердить, что сервер никак не отреагировал на запрос пользователя и прервал соединение.
449 Retry With
Код используется в расширениях компании Microsoft. Он сигнализирует о том, что запрос от клиента не может быть принят сервером. Причиной становятся неверно указанные параметры. Сама 449 ошибка говорит о необходимости скорректировать запрос и повторить его снова, подготовив к работе с сервером.
450 Blocked by Windows Parental Controls
450 код увидят дети, попавшие под действие системы «Родительский контроль» компании Microsoft. По сути, ошибка говорит о том, что с компьютера попытались зайти на заблокированный ресурс. Избежать этой ошибки можно изменением параметров родительского контроля.
451 Unavailable For Legal Reasons
Этот код сообщает клиенту, что он не может попасть на запрашиваемый ресурс из юридических соображений. Скорее всего, доступ был заблокирован из-за каких-нибудь государственных санкций, нового законодательства или цензуры со стороны властей. В общем, все вопросы к государству и провайдеру связи.
Читайте также
Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей
Подписаться
Список ошибок на стороне сервера (5xx)
Теперь поговорим об ошибках, которые возникают где-то на сервере. Все они связаны с запросами, которые не удается обработать на том конце. Пользователь зачастую в их появлении не виноват.
500 Internal Server Error
Этот код возникает, когда сервер сталкивается с непредвиденными обстоятельствами. Такими, которые и сам не может пояснить. Как, собственно, и завершить запрос со стороны пользователя. По факту, эта ошибка говорит нам что-то вроде «Я не могу подобрать более подходящий код ошибки, поэтому лови 500 и делай с этим, что хочешь». Мы писали о нем чуть подробнее тут.
Дело не в тебе, дело во мне (С)
501 Not Implemented
501 говорит нам, что функциональность, необходимая для обработки запроса со стороны клиента, попросту не реализована на сервере. Он не сможет корректно обработать используемый метод.
Иногда в теле ошибки еще пишут что-то в духе «Приходите попозже, возможно, в будущем нужная функция появится».
502 Bad Getaway
Можно встретить в том случае, если запрашиваемый сервер выступает в роли шлюза или прокси. Возникает из-за несогласования протоколов между вышестоящим серверов и его шлюзом. Рассказываем о том, как ее исправить, в этой статье.
503 Service Unavailable
Появляется, когда сервер не может обработать запрос клиента по одной из двух технических причин:
- Слишком много пользователей в текущий момент пытаются отправить запросы, и у сервера не остается ресурсов, чтобы ответить кому-либо еще.
- На сервере ведутся технические работы, временно блокирующие его работу.
Обычно ошибка 503 носит временный характер, и для ее решения достаточно немного подождать.
504 Gateway Timeout
Ошибка похожа на 408. Здесь же прокси-сервер пытается выйти на контакт с вышестоящим сервером, но не успевает это сделать до истечения тайм-аута. Отсюда и ошибка.
505 HTTP Version Not Supported
Этот код похож на 426. Он тоже связан с неподходящей версией протокола HTTP. В этом случае нужно обеспечить и клиента, и сервер единой версией. Она, как правило, указывается в запросе со стороны пользователя.
506 Variant Also Negotiates
Обычно с такой ошибкой сталкиваются только в том случае, если сервер изначально настроен неправильно. То есть это не сиюминутная проблема, а что-то серьезное на уровне базовой конфигурации. Тут придется потрудиться разработчикам. Выявить проблему и разрешить ее.
507 Insufficient Storage
Код 507 встречается в тех ситуациях, когда серверу не хватает пространства в хранилище для обработки запроса со стороны клиента. Проблема решается освобождением места или расширением доступного пространства. Тогда сервер сможет без проблем обработать запрос пользователя.
508 Loop Detected
Таким кодом сервер отзовется в случае, если заметит бесконечный цикл в запросе клиента. Можно расценивать его как провал запроса и выполняемой операции в целом.
509 Bandwidth Limit Exceeded
Возникает, если сервер начинает потреблять больше трафика, чем ему позволено.
510 Not Extended
Появляется, если клиент посылает запрос на использование какого-либо расширения, отсутствующего на сервере. Чтобы исправить проблему, надо убрать декларирование неподдерживаемого расширения из запроса или добавить поддержку на сервер.
511 Network Authentication Required
511 код говорит о том, что перед тем как выйти в сеть, надо авторизоваться (ввести логин и пароль). Можно воспринимать это неким PPPoE подключением, когда от клиента требуются данные для авторизации.
Заключение
Закончили. Это все ошибки, которыми отзывается HTTP, если на стороне сервера или клиента что-то пошло не так. Наткнуться на большую их часть довольно тяжело. Особенно, если вы раньше только серфили в интернете, а не занимались разработкой сайтов. А тем, кто входит в эту стезю, полезно знать основные ошибки, так как, скорее всего, придется не раз их исправлять.
- Co-author: Shi Li Xiao
Introduction to the
This article explores an HTTP request that returns 404 with a parameter in the Soul Gateway version 2.2.1
Bug emersion
Related Environment Configuration
First pull the code down, then switch to version 2.2.1, and the command looks something like this:
#To speed up the pull
git clone https://github.com.cnpmjs.org/lw1243925457/soul.git
#Switch to version 2.2.1Git fetch Origin 2.2.1:2.2.1 Git checkout 2.2.1Copy the code
If you have run the Soul gateway before, you will need to clean up your database. Here, remove the original Soul database and let version 2.2.1 create a new one
#Start mysql with Docker
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
#To reboot, you need to delete the Soul database and let the program rebuild itself
docker restart mysql
#Log in using the command to delete the original database
docker exec -ti mysql mysql -u root -p
drop database soul;
Copy the code
Soul — Admin
Modify the configuration file under the soul-admin module: soul-admin — application-local.yml
Change the mysql user name and password: root root
Modify link configuration: JDBC: mysql: / / localhost: 3306 / soul? useUnicode=truecharacterEncoding=utf-8allowPublicKeyRetrieval=trueuseSSL=false
Start soul-admin — SoulAdminBootstrap
If an error occurs related to SelectorTypeEnum, switch to JDK8
Start the Soul — the Bootstrap
Start soul-Bootstrap — SoulBootstrapApplication
Start the HTTP test
[[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]]
dependency
groupIdorg.dromara/groupId
artifactIdsoul-spring-boot-starter-client-springmvc/artifactId
version2.2.1/version
/dependency
Copy the code
Launch soul-test — soul-test-http — SoulTestHttpApplication
Request emersion
Access the admin interface: http://localhost:9095/ and view the list of plug-ins — Divide
Access problems link: http://localhost:9195/http/order/findById? If id=1, you can see that 404 appears
{
"timestamp": "Also thou T02:2021-01-18. 557 + 0000"."path": "/"."status": 404."error": "Not Found"."message": null."requestId": "84752141"
}
Copy the code
Direct access: http://localhost:8187/order/findById? Id =11, normal
{
"id": "11"."name": "hello world findById"
}
Copy the code
OK, the problem basically reappears, now start debugging
Source code for the Debug
Check the logs to cut in
According to my brother’s tip, we have also seen the relevant log of this problem request, which is roughly as follows
o.d.soul.plugin.base.AbstractSoulPlugin : divide selector success match , selector name :/http o.d.soul.plugin.base.AbstractSoulPlugin : divide rule success match ,rule name :/http/order/findById o.d.s.plugin.httpclient.WebClientPlugin : You request, The resulting urlPath is: http://192.168.101.104:8187? id=1111Copy the code
The urlpath is not the correct path. Let’s look directly at this class: WebClientPlugin
# WebClientPlugin
public MonoVoid execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
assertsoulContext ! =null; [[email protected]] [[email protected]]
In the above class, we can see that simply fetching the path, we need to trace the source of the path
Divide view
In the previous analysis, we learned that DividePlugin does routing configuration and writes real paths to Exchange. Let’s go to DividePlugin
# DividePlugin
protected MonoVoid doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
assertsoulContext ! =null;
final DivideRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), DivideRuleHandle.class);
final ListDivideUpstream upstreamList = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId());
if (CollectionUtils.isEmpty(upstreamList)) {
LOGGER.error("Divide upstream configuration error: {}", rule.toString());
Object error = SoulResultWarp.error(SoulResultEnum.CANNOT_FIND_URL.getCode(), SoulResultEnum.CANNOT_FIND_URL.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
final String ip = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
DivideUpstream divideUpstream = LoadBalanceUtils.selector(upstreamList, ruleHandle.getLoadBalance(), ip);
if (Objects.isNull(divideUpstream)) {
LOGGER.error("divide has no upstream");
Object error = SoulResultWarp.error(SoulResultEnum.CANNOT_FIND_URL.getCode(), SoulResultEnum.CANNOT_FIND_URL.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
Divide = 0; divide = 0; divide = 0; divide = 0; divide = 0; divide = 0
Exploring URL Settings
Then we need to continue to explore how the URL is set in, through the above analysis, there are two ways to set the URL, such as the following two codes:
final String rewriteURI = (String) exchange.getAttributes().get(Constants.REWRITE_URI);
final String realUrl = soulContext.getRealUrl();
Copy the code
Exchange-getattributes ().get(Constants.REWRITE_URI) mode exploration
By analogy with response Settings, the first URL Settings can be roughly as follows:
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
// Constants.REWRITE_URI
exchange.getAttributes().put(Constants.REWRITE_URI
Copy the code
Then use global search: CTRL + Shift + R, exchange.getAttributes().put(Constants.REWRITE_URI
# RewritePlugin
protected MonoVoid doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
String handle = rule.getHandle();
final RewriteHandle rewriteHandle = GsonUtils.getInstance().fromJson(handle, RewriteHandle.class);
if (Objects.isNull(rewriteHandle) || StringUtils.isBlank(rewriteHandle.getRewriteURI())) {
log.error("Rewriting rule can not configuration: {}", handle);
return chain.execute(exchange);
}
exchange.getAttributes().put(Constants.REWRITE_URI, rewriteHandle.getRewriteURI());
return chain.execute(exchange);
}
Copy the code
Search for the only class with this code: RewritePlugin, and then we break the point, and then can’t go into the logic, look at the console, it’s off. So let’s leave it there and look at the second setting
Exploration of soulContext.getrealURL () Settings
Using analogy, we can guess that the code for the setting should be: soulContext.setrealURL
We search and found only a code of success, in the class DefaultSoulContextBuilder, roughly as follows:
# DefaultSoulContextBuilder
private void setSoulContextByHttp(final SoulContext soulContext, final String path) {
String contextPath = "/";
String[] splitList = StringUtils.split(path, "/");
if(splitList.length ! =0) {
contextPath = contextPath.concat(splitList[0]);
}
String realUrl = path.substring(contextPath.length());
soulContext.setContextPath(contextPath);
soulContext.setModule(contextPath);
soulContext.setMethod(realUrl);
We put a breakpoint on this function, but unfortunately, it doesn’t enter either. Instant head ??????? What kind of fat thing is this? It’s not set
Don’t abandon, don’t give up, how to continue. Seeing that the realURL comes from Path, we continue to pursue its source and find that the following function of the same class is called: transform, one level above build
# DefaultSoulContextBuilder
private SoulContext transform(final ServerHttpRequest request, final MetaData metaData) {
final String appKey = request.getHeaders().getFirst(Constants.APP_KEY);
final String sign = request.getHeaders().getFirst(Constants.SIGN);
final String timestamp = request.getHeaders().getFirst(Constants.TIMESTAMP);
SoulContext soulContext = new SoulContext();
String path = request.getURI().getPath();
soulContext.setPath(path);
if (Objects.nonNull(metaData) metaData.getEnabled()) {
if (RpcTypeEnum.SPRING_CLOUD.getName().equals(metaData.getRpcType())) {
setSoulContextByHttp(soulContext, path);
soulContext.setRpcType(metaData.getRpcType());
} else{ setSoulContextByDubbo(soulContext, metaData); }}else {
setSoulContextByHttp(soulContext, path);
soulContext.setRpcType(RpcTypeEnum.HTTP.getName());
}
soulContext.setAppKey(appKey);
soulContext.setSign(sign);
soulContext.setTimestamp(timestamp);
soulContext.setStartDateTime(LocalDateTime.now());
Optional.ofNullable(request.getMethod()).ifPresent(httpMethod - soulContext.setHttpMethod(httpMethod.name()));
return soulContext;
}
public SoulContext build(final ServerWebExchange exchange) {
final ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
MetaData metaData = MetaDataCache.getInstance().obtain(path);
if (Objects.nonNull(metaData) metaData.getEnabled()) {
exchange.getAttributes().put(Constants.META_DATA, metaData);
}
return transform(request, metaData);
}
Copy the code
Click a breakpoint in the build function and, thank Goodness, enter the call stack to find the familiar GlobalPlugin making the call
# GlobalPlugin
public MonoVoid execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final HttpHeaders headers = request.getHeaders();
final String upgrade = headers.getFirst("Upgrade");
SoulContext soulContext;
if (StringUtils.isBlank(upgrade) || !"websocket".equals(upgrade)) {
soulContext = builder.build(exchange);
} else {
final MultiValueMapString, String queryParams = request.getQueryParams();
soulContext = transformMap(queryParams);
}
exchange.getAttributes().put(Constants.CONTEXT, soulContext);
return chain.execute(exchange);
}
Copy the code
Port the following functions and debug step by step. As you can see in the comments below: we are making an HTTP request, but we are walking into Dubbo’s logic, which is very wrong
private SoulContext transform(final ServerHttpRequest request, final MetaData metaData) {
Let’s use the following diff tool to see how the latest version of the code differs from the current version:
- Diffinity — Lightweight file comparison tool for Windows
As you can see from the figure above, the latest version of the code takes a more rigorous approach and sets the default request type to HTTP so that HTTP processing logic can be followed in the new version of the code
Let’s change the code to make HTTP the default processing, and the code looks like this:
private SoulContext transform(final ServerHttpRequest request, final MetaData metaData) {
final String appKey = request.getHeaders().getFirst(Constants.APP_KEY);
final String sign = request.getHeaders().getFirst(Constants.SIGN);
final String timestamp = request.getHeaders().getFirst(Constants.TIMESTAMP);
SoulContext soulContext = new SoulContext();
String path = request.getURI().getPath();
soulContext.setPath(path);
if (Objects.nonNull(metaData) metaData.getEnabled()) {
if (RpcTypeEnum.SPRING_CLOUD.getName().equals(metaData.getRpcType())) {
setSoulContextByHttp(soulContext, path);
soulContext.setRpcType(metaData.getRpcType());
} else if (RpcTypeEnum.DUBBO.getName().equals(metaData.getRpcType())) {
setSoulContextByDubbo(soulContext, metaData);
} else{ setSoulContextByHttp(soulContext, path); soulContext.setRpcType(RpcTypeEnum.HTTP.getName()); }}else {
setSoulContextByHttp(soulContext, path);
soulContext.setRpcType(RpcTypeEnum.HTTP.getName());
}
soulContext.setAppKey(appKey);
soulContext.setSign(sign);
soulContext.setTimestamp(timestamp);
soulContext.setStartDateTime(LocalDateTime.now());
Optional.ofNullable(request.getMethod()).ifPresent(httpMethod - soulContext.setHttpMethod(httpMethod.name()));
return soulContext;
}
Copy the code
Restart, send the request: http://127.0.0.1:9195/http/order/findById? Id =1111, OK, very impressive success
{
"id": "1111"."name": "hello world findById"
}
Copy the code
At this point, we were able to locate and fix the bug (not helpful, but happy)
If (objects.nonnull (metaData) metadata.getenabled ())
conclusion
This article examines the 404 error in HTTP requests in Version 2.2.1 of Soul Gateway
From the above analysis, we can see that in 2.2.1, HTTP requests other than Spring Cloud will have errors, which is a bit serious bug
I also realized the importance of the GlobalPlugin plugin, which not only sets the type, but also sets the real back-end server path, which is the core of the plugin. The rewrite plug-in also has the ability to set paths
With a new understanding, update our request processing chart:
Soul Gateway source code analysis article list
Github
- Soul source reading (a) overview
- Soul source code reading (two) the initial run of the code
- HTTP request processing overview
- Dubbo Request Overview
- Soul Gateway source code reading (five) request type exploration
- Soul Gateway source code reading (6) Sofa request processing overview
The Denver nuggets
- Soul Gateway source code read (a) overview # nuggets article # juejin.cn/post/691786…
- Soul Gateway source code reading (two) initial run # nuggets article # juejin.cn/post/691786…
- Soul Gateway source code read (three) request processing overview # nuggets article # juejin.cn/post/691786…
- Dubbo request Overview # Nuggets article # juejin.cn/post/691786…
- Soul Gateway source code read (five) request types explore # nuggets article # juejin.cn/post/691857…
- Soul Gateway source code read (6) Sofa request processing overview # nuggets article # juejin.cn/post/691873…
Let’s say that someone makes a request to your server with data that is in the correct format, but is simply not «good» data. So for example, imagine that someone posted a String value to an API endpoint that expected a String value; but, the value of the string contained data that was blacklisted (ex. preventing people from using «password» as their password). What HTTP status code would you return?
Until now, I would have returned a «400 Bad Request», which, according to the w3.org, means:
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
This description doesn’t quite fit the circumstance; but, if you go by the list of core HTTP status codes defined in the HTTP/1.1 protocol, it’s probably your best bet.
Recently, however, Jamie Krug pointed out [to me] that popular APIs are starting to use HTTP extensions to get more granular with their error reporting. Specifically, many APIs, like Twitter and Recurly, are using the status code «422 Unprocessable Entity» as defined in the HTTP extension for WebDAV. HTTP status code 422 states:
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415 (Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
Going back to our password example from above, this 422 status code feels much more appropriate. The server understands what you’re trying to do; and it understands the data that you’re submitting; it simply won’t let that data be processed.
HTTP status code 422 feels like a much more appropriate response for situations where the data is understood, but is still not valid. I think I’ll start using this going forward. Thanks Jamie!
I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
No, you should not. HTTP codes are meant for the HTTP layer of your application. Business rules is completely different layer and is application specific, so you need to come up with your own «protocol».
Imagine an apocalypse happens and you have to switch from HTTP protocol to using Pigeons. Pigeons don’t have any return codes, so you would need to change your business layer to accomodate for that. But your business has not really changed in any way so you shouldn’t need to change business layer. It shows a tight coupling between those two layers (transport and business).
Back to the question: What you should do is return «200 OK» with a body describing what happened with the request. The specification clearly says so:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1.
200 OK
The request has succeeded. The information returned with the response is dependent on the method used in the request, for example
POST an entity describing or containing the result of the action;
Has your HTTP request succeeded? Yes it has, the web server knows what to do with that request (e.g. pass it on to the server part of your application). Web server then passes this request to the server part of your application, which takes the POSTed data, processes them (validates them in your case) and returns a normal answer (in the body of an HTTP response) to the client part of your application. This answer from the server part of application can be either «Great, the data you sent me are valid» or «I’m sorry, the data you sent are not valid». And it is up to your client part of application to understand what the answer means.
PS: «400 Bad Request» means, that the web server did not understand what you want from it. It means that your server part of your application did not even receive the request. Or at least that’s what it’s meant to mean
EDIT: I just realized, that you’re doing GET request, not POST. This is a bad idea because GET should not change the state of the application. GET is supposed to simply retrieve data from the server. But in your request you are actually changing the state of the application, so you should really be using POST.
- Error description
- Short error description in the response
- Example of an error message
If an error occurs, the request processing stops, and the server returns an HTTP response code that identifies the error. In addition to the code, the response contains a short error description.
The error message is returned in the format specified in the request URL after the method name or in the Accept HTTP header.
The error description is passed in the error parameter. This parameter contains the error code (the code parameter) and a short error description (the message parameter).
Code |
Name |
Explanation |
---|---|---|
200 |
OK |
The request is successfully completed. |
206 |
Partial Content |
The request is partially completed. |
400 |
Bad Request |
The request is invalid. |
401 |
Unauthorized |
The request doesn’t include authorization data. |
403 |
Forbidden |
Incorrect authorization data is specified in the request, or access to the requested resource is denied. |
404 |
Not Found |
The requested resource isn’t found. |
405 |
Method Not Allowed |
The requested method isn’t supported for the specified resource. |
415 |
Unsupported Media Type |
The requested content type isn’t supported by the method. |
420 |
Enhance Your Calm |
The resource access restriction is exceeded. |
500 |
Internal Server Error |
Internal server error. Try calling the method after a while. If the error persists, contact the Yandex.Market support service. |
503 |
Service Unavailable |
The server is temporarily unavailable due to high load. Try calling the method after a while. |
-
For the
400 Bad Request
error:Description
Explanation
Possible solution
Collection of field must not be empty
The parameter must not be empty.
Specify at least one element for the parameter.
Invalid status: 'status'
Invalid status is specified.
Check if the sent status is correct for order filtering by status.
JSON: {message}
The JSON data format contains an error.
Check if the data passed in the request body has the correct JSON format.
Missing field
The required parameter isn’t specified.
Specify a value for the required parameter.
The request is too big
The HTTP request size limit is exceeded.
Cut the request size by reducing the amount of the sent data.
Too long time period. Maximum is 'maxPeriod' days
The specified date range is too large. Maximum range — maxPeriod.
Reduce the date range to filter orders by date.
Unexpected character 'character': expected a valid value 'values'
Invalid character.
Check the request body encoding. The required encoding is UTF-8.
Unexpected end of content
The request body ends unexpectedly.
Check if the data passed in the request body has the correct format.
Value / length of field (value) must be between min and max [exclusively]
The parameter value (length) must be between the min and max values and not equal to them.
Check if the parameter value is correct.
Value / length of field (value) must be greater / less than [or equal to] limit
The parameter value (length) must be equal to or greater than (less than) the specified limit value.
Check if the parameter value is correct.
Value of field has too high scale: 'price'
The accuracy of the parameter is set too high.
Set the parameter values with less precision.
Value of field must match the pattern: 'regExp'
The parameter value must match the regular expression.
Check if the parameter value is correct.
XML: {message}
The XML data format contains an error.
Check if the data passed in the request body has the correct XML format.
Other short descriptions that can be found in messages about this error are provided in the descriptions of the corresponding resources.
-
For the
401 Unauthorized
error:Description
Explanation
Possible solution
Unsupported authorization type specified in Authorization header
Authorization type passed in the Authorization HTTP header isn’t supported.
Check if the authorization data is correct.
Authorization header has invalid syntax
The Authorization HTTP header format is incorrect.
Check if the authorization data is correct.
OAuth credentials are not specified
The request doesn’t include authorization data.
Check that the authorization data is correct.
OAuth token is not specified
The request doesn’t include the authorization token (the oauth_token parameter).
Check if the authorization data is correct.
OAuth client id is not specified
The request doesn’t include the application ID (the oauth_client_id parameter).
Check if the authorization data is correct.
-
For the
403 Forbidden
error:Description
Explanation
Possible solution
Access denied
Access to the specified resource is prohibited.
Check if the resource is specified correctly, and if the authorized user login has access to it.
Access to API denied for the client / campaign
The client or store isn’t allowed to access the Yandex.Market Partner API.
Agency clients should contact their agency about getting access to the Yandex.Market Partner API.
Client id is invalid
The specified application ID (the oauth_client_id parameter) is invalid.
Check if the authorization data is correct. If they are correct, get a new app ID, repeat the request with the new authorization data.
Scope is invalid
The specified authorization token (the oauth_token parameter) doesn’t have the necessary set of rights.
Get a new authorization token, mention the right to use the Yandex.Market Partner API when you receive it, and repeat the request with the new authorization data.
Token is invalid
The specified authorization token (parameter oauth_token) is invalid.
Check if the authorization data is correct. If they are correct, get a new authorization token, repeat the request with the new authorization data.
User account is disabled
The user account for which the specified authorization token was issued is blocked.
Contact the Yandex.Market support service.
-
For the
404 Not Found
error:Description
Explanation
Possible solution
Feed not found: 'feedId'
The price list specified in the request isn’t found.
Check if the sent price list ID is correct.
Login not found: 'login'
The username specified in the request isn’t found.
Check if the sent username is correct.
Model not found: 'modelId'
The model specified in the request isn’t found.
Check if the model ID you are passing is correct.
-
For the
405 Method Not Allowed
error:Description
Explanation
Possible solution
Request method 'method' not supported
The requested HTTP method isn’t supported.
Check the methods supported by the resource. You can find the list of methods in the Requests reference section.
-
For the
415 Unsupported Media Type
error:Description
Explanation
Possible solution
Content type 'content-type' not supported
The requested content type isn’t supported.
Pass one of the supported content types.
Missing Content-Type
The content type isn’t specified.
Pass the content type.
Unknown content-type: 'content-type'
The requested content type is unknown.
Pass one of the supported content types.
-
For the
420 Enhance Your Calm
error:Description
Explanation
Possible solution
Hit rate limit of 'N' parallel requests
Exceeded the global limit on the number of simultaneous requests to the Yandex.Market Partner API.
Reduce the number of concurrent requests to the partner API within a single store or partner to N requests.
Hit rate limit of 'N' requests per 'period' for resource 'R'
The resource restriction for the N number of requests to the R resource over the period for the same store or partner is exceeded.
The time until which the limit applies is specified in the X-RateLimit-Resource-Until header. You can use of the resource after the specified time.
-
For the
503 Service Unavailable
error:Description
Explanation
Possible solution
Service temporarily unavailable. Please, try again later
The server is temporarily unavailable due to high load.
Try repeating the request after a while.
Request example:
GET /v2/campaigns.xml HTTP/1.1
Host: api.partner.market.yandex.ru
Accept: */*
Authorization: OAuth oauth_token=,oauth_client_id=b12320932d4e401ab6e1ba43d553d433
Response example:
<response>
<errors>
<error code="UNAUTHORIZED" message="OAuth token is not specified"/>
</errors>
<error code="401">
<message>OAuth token is not specified</message>
</error>
</response>
Request example:
GET /v2/campaigns.json HTTP/1.1
Host: api.partner.market.yandex.ru
Accept: */*
Authorization: OAuth oauth_token=,oauth_client_id=b12320932d4e401ab6e1ba43d553d433
Response example:
{
"errors":
[
{
"code": "UNAUTHORIZED",
"message": "OAuth token is not specified"
}
],
"error":
{
"code": 401,
"message": "OAuth token is not specified"
}
}
Error codes are almost the last thing that you want to see in an API response. Generally speaking, it means one of two things — something was so wrong in your request or your handling that the API simply couldn’t parse the passed data, or the API itself has so many problems that even the most well-formed request is going to fail. In either situation, traffic comes crashing to a halt, and the process of discovering the cause and solution begins.
That being said, errors, whether in code form or simple error response, are a bit like getting a shot — unpleasant, but incredibly useful. Error codes are probably the most useful diagnostic element in the API space, and this is surprising, given how little attention we often pay them.
Today, we’re going to talk about exactly why error responses and handling approaches are so useful and important. We’ll take a look at some common error code classifications the average user will encounter, as well as some examples of these codes in action. We’ll also talk a bit about what makes a “good” error code and what makes a “bad” error code, and how to ensure your error codes are up to snuff.
The Value of Error Codes
As we’ve already said, error codes are extremely useful. Error codes in the response stage of an API is the fundamental way in which a developer can communicate failure to a user. This stage, sitting after the initial request stage, is a direct communication between client and API. It’s often the first and most important step towards not only notifying the user of a failure, but jump-starting the error resolution process.
A user doesn’t choose when an error is generated, or what error it gets — error situations often arise in instances that, to the user, are entirely random and suspect. Error responses thus are the only truly constant, consistent communication the user can depend on when an error has occurred. Error codes have an implied value in the way that they both clarify the situation, and communicate the intended functionality.
Consider for instance an error code such as “401 Unauthorized – Please Pass Token.” In such a response, you understand the point of failure, specifically that the user is unauthorized. Additionally, however, you discover the intended functionality — the API requires a token, and that token must be passed as part of the request in order to gain authorization.
With a simple error code and resolution explanation, you’ve not only communicated the cause of the error, but the intended functionality and method to fix said error — that’s incredibly valuable, especially for the amount of data that is actually returned.
HTTP Status Codes
Before we dive deeper into error codes and what makes a “good” code “good,” we need to address the HTTP Status Codes format. These codes are the most common status codes that the average user will encounter, not just in terms of APIs but in terms of general internet usage. While other protocols exist and have their own system of codes, the HTTP Status Codes dominate API communication, and vendor-specific codes are likely to be derived from these ranges.
1XX – Informational
The 1XX range has two basic functionalities. The first is in the transfer of information pertaining to the protocol state of the connected devices — for instance, 101 Switching Protocols
is a status code that notes the client has requested a protocol change from the server, and that the request has been approved. The 1XX range also clarifies the state of the initial request. 100 Continue
, for instance, notes that a server has received request headers from a client, and that the server is awaiting the request body.
2XX – Success
The 2XX range notes a range of successes in communication, and packages several responses into specific codes. The first three status codes perfectly demonstrate this range – 200 OK
means that a GET or POST request was successful, 201 Created
confirms that a request has been fulfilled and a new resource has been created for the client, and 202 Accepted
means that the request has been accepted, and that processing has begun.
3XX – Redirection
The 3XX range is all about the status of the resource or endpoint. When this type of status code is sent, it means that the server is still accepting communication, but that the point contacted is not the correct point of entry into the system. 301 Moved Permanently
verifies that the client request did in fact reach the correct system, but that this request and all future requests should be handled by a different URI. This is very useful in subdomains and when moving a resource from one server to another.
4XX – Client Error
The 4XX series of error codes is perhaps the most famous due to the iconic 404 Not Found
status, which is a well-known marker for URLs and URIs that are incorrectly formed. Other more useful status codes for APIs exist in this range, however.
414 URI Too Long
is a common status code, denoting that the data pushed through in a GET request is too long, and should be converted to a POST request. Another common code is 429 Too many Requests
, which is used for rate limiting to note a client is attempting too many requests at once, and that their traffic is being rejected.
5XX – Server Error
Finally the 5XX range is reserved for error codes specifically related to the server functionality. Whereas the 4XX range is the client’s responsibility (and thus denotes a client failure), the 5XX range specifically notes failures with the server. Error codes like 502 Bad Gateway
, which notes the upstream server has failed and that the current server is a gateway, further expose server functionality as a means of showing where failure is occurring. There are less specific, general failures as well, such as 503 Service Unavailable
.
Making a Good Error Code
With a solid understanding of HTTP Status Codes, we can start to dissect what actually makes for a good error code, and what makes for a bad error code. Quality error codes not only communicate what went wrong, but why it went wrong.
Overly opaque error codes are extremely unhelpful. Let’s imagine that you are attempting to make a GET request to an API that handles digital music inventory. You’ve submitted your request to an API that you know routinely accepts your traffic, you’ve passed the correct authorization and authentication credentials, and to the best of your knowledge, the server is ready to respond.
You send your data, and receive the following error code – 400 Bad Request
. With no additional data, no further information, what does this actually tell you? It’s in the 4XX range, so you know the problem was on the client side, but it does absolutely nothing to communicate the issue itself other than “bad request.”
This is when a “functional” error code is really not as functional as it should be. That same response could easily be made helpful and transparent with minimal effort — but what would this entail? Good error codes must pass three basic criteria in order to truly be helpful. A quality error code should include:
- An HTTP Status Code, so that the source and realm of the problem can be ascertained with ease;
- An Internal Reference ID for documentation-specific notation of errors. In some cases, this can replace the HTTP Status Code, as long as the internal reference sheet includes the HTTP Status Code scheme or similar reference material.
- Human readable messages that summarize the context, cause, and general solution for the error at hand.
Include Standardized Status Codes
First and foremost, every single error code generated should have an attached status code. While this often takes the form of an internal code, it typically takes the form of a standardized status code in the HTTP Status Code scheme. By noting the status using this very specific standardization, you not only communicate the type of error, you communicate where that error has occurred.
There are certain implications for each of the HTTP Status Code ranges, and these implications give a sense as to the responsibility for said error. 5XX errors, for instance, note that the error is generated from the server, and that the fix is necessarily something to do with server-related data, addressing, etc. 4XX, conversely, notes the problem is with the client, and specifically the request from the client or the status of the client at that moment.
By addressing error codes using a default status, you can give a very useful starting point for even basic users to troubleshoot their errors.
Give Context
First and foremost, an error code must give context. In our example above, 400 Bad Request
means nothing. Instead, an error code should give further context. One such way of doing this is by passing this information in the body of the response in the language that is common to the request itself.
For instance, our error code of 400 Bad Request
can easily have a JSON body that gives far more useful information to the client:
< HTTP/1.1 400 Bad Request
< Date: Wed, 31 May 2017 19:01:41 GMT
< Server: Apache/2.4.25 (Ubuntu)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: application/json
{ "error" : "REQUEST - BR0x0071" }
This error code is good, but not great. What does it get right? Well, it supplies context, for starters. Being able to see what the specific type of failure is shows where the user can begin the problem solving process. Additionally, and vitally, it also gives an internal reference ID in the form of “BR0x0071”, which can be internally referenced.
While this is an ok error code, it only meets a fraction of our requirements.
Human Readability
Part of what makes error codes like the one we just created so powerful is that it’s usable by humans and machines alike. Unfortunately, this is a very easy thing to mess up — error codes are typically handled by machines, and so it’s very tempting to simply code for the application rather than for the user of said application.
In our newly formed example, we have a very clear error to handle, but we have an additional issue. While we’ve added context, that context is in the form of machine-readable reference code to an internal error note. The user would have to find the documentation, look up the request code “BRx0071”, and then figure out what went wrong.
We’ve fallen into that trap of coding for the machine. While our code is succinct and is serviceable insomuch as it provides context, it does so at the cost of human readability. With a few tweaks, we could improve the code, while still providing the reference number as we did before:
< HTTP/1.1 400 Bad Request
< Date: Wed, 31 May 2017 19:01:41 GMT
< Server: Apache/2.4.25 (Ubuntu)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: application/json
{ "error" : "Bad Request - Your request is missing parameters. Please verify and resubmit. Issue Reference Number BR0x0071" }
With such a response, not only do you get the status code, you also get useful, actionable information. In this case, it tells the user the issue lies within their parameters. This at least offers a place to start troubleshooting, and is far more useful than saying “there’s a problem.”
While you still want to provide the issue reference number, especially if you intend on integrating an issue tracker into your development cycle, the actual error itself is much more powerful, and much more effective than simply shooting a bunch of data at the application user and hoping something sticks.
Good Error Examples
Let’s take a look at some awesome error code implementations on some popular systems.
Twitter API is a great example of descriptive error reporting codes. Let’s attempt to send a GET request to retrieve our mentions timeline.
https://api.twitter.com/1.1/statuses/mentions_timeline.json
When this is sent to the Twitter API, we receive the following response:
HTTP/1.1 400 Bad Request
x-connection-hash:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set-cookie:
guest_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Date:
Thu, 01 Jun 2017 03:04:23 GMT
Content-Length:
62
x-response-time:
5
strict-transport-security:
max-age=631138519
Connection:
keep-alive
Content-Type:
application/json; charset=utf-8
Server:
tsa_b
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
Looking at this data, we can generally figure out what our issue is. First, we’re told that we’ve submitted a 400 Bad Request
. This tells us that the problem is somewhere in our request. Our content length is acceptable, and our response time is well within normal limits. We can see, however, that we’re receiving a unique error code that Twitter itself has denoted — “215”, with an attached message that states “Bad Authentication data”.
This error code supplies both valuable information as to why the error has occurred, and also how to rectify it. Our error lies in the fact that we did not pass any authentication data whatsoever — accordingly, error 215 is referenced, which tells us the fix is to supply said authentication data, but also gives us a number to reference on the internal documentation of the Twitter API.
For another great example, let’s look at another social network. Facebook’s Graph API allows us to do quite a lot as long as we have the proper authentication data. For the purposes of this article, all personal information will be blanked out for security purposes.
First, let’s pass a GET request to ascertain some details about a user:
https://graph.facebook.com/v2.9/me?fields=id%2Cname%2Cpicture%2C%20picture&access_token=xxxxxxxxxxx
This request should give us a few basic fields from this user’s Facebook profile, including id, name, and picture. Instead, we get this error response:
{
"error": {
"message": "Syntax error "Field picture specified more than once. This is only possible before version 2.1" at character 23: id,name,picture,picture",
"type": "OAuthException",
"code": 2500,
"fbtrace_id": "xxxxxxxxxxx"
}
}
While Facebook doesn’t directly pass the HTTP error code in the body, it does pass a lot of useful information. The “message” area notes that we’ve run into a syntax error, specifically that we’ve defined the “picture” field more than once. Additionally, this field lets us know that this behavior was possible in previous versions, which is a very useful tool to communicate to users a change in behavior from previous versions to the current.
Additionally, we are provided both a code and an fbtrace_id
that can be used with support to identify specific issues in more complex cases. We’ve also received a specific error type, in this case OAuthException
, which can be used to narrow down the specifics of the case even further.
Bing
To show a complex failure response code, let’s send a poorly formed (essentially null) GET request to Bing.
HTTP/1.1 200
Date:
Thu, 01 Jun 2017 03:40:55 GMT
Content-Length:
276
Connection:
keep-alive
Content-Type:
application/json; charset=utf-8
Server:
Microsoft-IIS/10.0
X-Content-Type-Options:
nosniff
{"SearchResponse":{"Version":"2.2","Query":{"SearchTerms":"api error codes"},"Errors":[{"Code":1001,"Message":"Required parameter is missing.","Parameter":"SearchRequest.AppId","HelpUrl":"httpu003au002fu002fmsdn.microsoft.comu002fen-usu002flibraryu002fdd251042.aspx"}]}}
This is a very good error code, perhaps the best of the three we’ve demonstrated here. While we have the error code in the form of “1001”, we also have a message stating that a parameter is missing. This parameter is then specifically noted as “SearchRequestAppId”, and a “HelpUrl” variable is passed as a link to a solution.
In this case, we’ve got the best of all worlds. We have a machine readable error code, a human readable summary, and a direct explanation of both the error itself and where to find more information about the error.
Spotify
Though 5XX errors are somewhat rare in modern production environments, we do have some examples in bug reporting systems. One such report noted a 5XX error generated from the following call:
GET /v1/me/player/currently-playing
This resulted in the following error:
[2017-05-02 13:32:14] production.ERROR: GuzzleHttpExceptionServerException: Server error: `GET https://api.spotify.com/v1/me/player/currently-playing` resulted in a `502 Bad Gateway` response:
{
"error" : {
"status" : 502,
"message" : "Bad gateway."
}
}
So what makes this a good error code? While the 502 Bad gateway error seems opaque, the additional data in the header response is where our value is derived. By noting the error occurring in production and its addressed variable, we get a general sense that the issue at hand is one of the server gateway handling an exception rather than anything external to the server. In other words, we know the request entered the system, but was rejected for an internal issue at that specific exception address.
When addressing this issue, it was noted that 502 errors are not abnormal, suggesting this to be an issue with server load or gateway timeouts. In such a case, it’s almost impossible to note granularly all of the possible variables — given that situation, this error code is about the best you could possibly ask for.
Conclusion
Much of an error code structure is stylistic. How you reference links, what error code you generate, and how to display those codes is subject to change from company to company. However, there has been headway to standardize these approaches; the IETF recently published RFC 7807, which outlines how to use a JSON object as way to model problem details within HTTP response. The idea is that by providing more specific machine-readable messages with an error response, the API clients can react to errors more effectively.
In general, the goal with error responses is to create a source of information to not only inform the user of a problem, but of the solution to that problem as well. Simply stating a problem does nothing to fix it – and the same is true of API failures.
The balance then is one of usability and brevity. Being able to fully describe the issue at hand and present a usable solution needs to be balanced with ease of readability and parsability. When that perfect balance is struck, something truly powerful happens.
While it might seem strange to wax philosophically about error codes, they are a truly powerful tool that go largely underutilized. Incorporating them in your code is not just a good thing for business and API developer experience – they can lead to more positive end user experience, driving continuous adoption and usage.
Коды ответа (состояния) HTTP, которые может возвращать ЮKassa.
Код ответа HTTP | Код ошибки | Описание |
---|---|---|
200 | — |
Запрос успешно обработан. Для POST и GET-запросов ответ содержит созданный, измененный или запрашиваемый объект в актуальном статусе. Для DELETE-запросов тело объекта пустое. Подробнее об обработке HTTP 200 |
400 | invalid_request |
Неправильный запрос, нарушен синтаксис или логика запроса. Чаще всего этот статус выдается из-за нарушения правил взаимодействия по API. Подробнее об обработке HTTP 400 |
401 | invalid_credentials |
Некорректные данные для аутентификации запроса (идентификатор и секретный ключ, OAuth-токен). Подробнее об обработке HTTP 401 |
403 | forbidden |
Не хватает прав для совершения операции. Подробнее об обработке HTTP 403 |
404 | not_found |
Запрашиваемый ресурс не найден. Подробнее об обработке HTTP 404 |
405 | — |
Некорректный HTTP-метод запроса. Например, ошибка возникает при попытке отправить запрос на отмену платежа методом GET вместо POST. Подробнее об обработке HTTP 405 |
415 | — |
Некорректный тип контента для POST-запроса. Подробнее об обработке HTTP 415 |
429 | too_many_requests |
Превышен лимит запросов в единицу времени. Подробнее об обработке HTTP 429 |
500 | internal_server_error |
Технические неполадки на стороне ЮKassa. Результат обработки запроса неизвестен. Подробнее об обработке HTTP 500 |
Если запрос обработан успешно, API вернет HTTP 200 и тело ответа с результатом выполнения запроса. Формат тела ответа зависит от запроса (подробнее в Справочнике API).
Пример ответа
HTTP/2 200
Server: nginx
Date: Thu, 21 Apr 2022 07:39:21 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 579
Signature: v1 29f31de9 1 MGUCMQCIu97XzcGGvH2C5C+4udkuX5xcS2qcgnSJqFRCZMKFSukrhBntD7dkzhTqYHErI60CMH1e48+07gTTd7YUIPZbZCwXL7d13qMR6hEJwi1CeSPLLZSvBChn3TkQzQY0dbyBRA==
Strict-Transport-Security: max-age=15768000
{
"id" : "29f31de9-000f-5000-a000-109987b98a6a",
"status" : "pending",
"amount" : {
"value" : "2.00",
"currency" : "RUB"
},
"description" : "Заказ №1",
"recipient" : {
"account_id" : "152368",
"gateway_id" : "459728"
},
"created_at" : "2022-04-21T07:39:21.471Z",
"confirmation" : {
"type" : "redirect",
"confirmation_url" : "https://yoomoney.ru/checkout/payments/v2/contract?orderId=29f31de9-000f-5000-a000-109987b98a6a"
},
"test" : false,
"paid" : false,
"refundable" : false,
"metadata" : {
"order_id" : "37"
}
}
У некоторых объектов, например у платежей, есть статус. Он отражает результат выполнения операции. Например, если платеж создан, но пользователь еще не подтвердил его, объект платежа будет в статусе
pending
. Если оплата перечислена на баланс вашего магазина, статус объекта платежа будет
succeeded
. Если по каким-то причинам не удалось провести платеж, то статус будет
canceled
, объект платежа будет содержать данные о причинах отмены.
Если в ответ на запрос вы получили объект в статусе
pending
, вам нужно дождаться, когда объект перейдет в финальный статус. Узнать об изменении статуса можно двумя способами:
- Подписаться на входящие уведомления и дождаться уведомления. Подробнее о входящих уведомлениях
- Повторить запрос с теми же данными и с тем же ключом идемпотентности или запросить информацию об объекте методом GET. Если статус объекта не изменится, рекомендуется повторять запрос с возрастающим разумным интервалом (например, можно использовать последовательность Фибоначчи).
Если созданный объект должен был уже перейти в другой статус (например, закончилось время, отведенное на подтверждение платежа пользователем), а объект всё еще остается в статусе
pending
, обратитесь в техническую поддержку.
Если запрос некорректный с точки зрения синтаксиса или логики API ЮKassa, API вернет HTTP 400. В теле ответа будет указана возникшая ошибка. Описание параметров тела ответа
Пример ответа
HTTP/2 400
Server: nginx
Date: Thu, 21 Apr 2022 07:51:44 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 238
Signature: v1 29f320d0 1 MGQCMHU++9/SylfnZ4u5PWfyGtjib5WsLId2Jy2OnsD7+evQpETko30oTuUNNXe79VaecgIwUmiabma6qGobOP8+5KfjblFdrXg91PcwbsOX/yEIsspGnZqBKS067ulHu0UUze93
{
"type" : "error",
"id" : "55a02ced-be5d-462d-a6fb-0ace18881671",
"code" : "invalid_request",
"description" : "Idempotence key is too long. Send the value in accordance with the documentation",
"parameter" : "Idempotence-Key"
}
Примеры ситуаций, в которых может возвращаться код ответа HTTP 400:
- отсутствуют обязательные параметры;
- ошибка в значении параметра (не тот формат, недопустимое значение);
- нарушена логика формирования запроса (например, нужно передать один из двух параметров, а переданы оба, или значение в одном параметре не соответствует значению в другом параметре);
- что-то не так с ключом идемпотентности.
Причина возникновения ошибки указана в теле ответа, в параметре
description
. При необходимости тело ответа содержит
parameter
с названием параметра, из-за которого возникла ошибка.
Поправьте ошибки и повторите запрос с новым ключом идемпотентности.
Эти ошибки необходимо поправить в процессе интеграции, чтобы при проведении реальных операций все запросы были корректными и ЮKassa могла их обработать.
Если в заголовке запроса отсутствует параметр
Authorization
или с переданными данными для аутентификации что-то не так, API вернет HTTP 401. В теле ответа будет указана возникшая ошибка. Описание параметров тела ответа
Пример ответа
HTTP/2 401
Server: nginx
Date: Thu, 21 Apr 2022 07:49:13 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 202
WWW-Authenticate: Basic
Signature: v1 29f32039 1 MGQCME00FWXiu+F4Jdj1vddlsiZrcEwNy3XaCoXPpJF+Fpth62D/Hxru2fWBIAMKNxaT5gIwKaUvlJg/Thj5B0mIbn8+NG4+vegpzpSUjnTRcDAxwJGve9bcj+gliWBbSeWSzZd/
{
"type" : "error",
"id" : "c7e8fadc-c21f-4074-b1ac-d85234eeca1d",
"code" : "invalid_credentials",
"description" : "Authentication by given credentials failed",
"parameter" : "Authorization"
}
- HTTP Basic Auth (идентификатор магазина и секретный ключ);
- OAuth (OAuth-токен) — относится только к тем, кто использует API для партнеров.
Примеры ситуаций, в которых может возвращаться код ответа HTTP 401 при использовании HTTP Basic Auth:
- в запросе нет идентификатора или секретного ключа;
- идентификатор и секретный ключ указаны в неправильном порядке или формате;
- идентификатор не соответствует тому магазину, в который вы хотите провести операцию, или в идентификаторе опечатки;
- указанный секретный ключ неактуальный или содержит опечатки.
Причина возникновения ошибки указана в теле ответа, в параметре
description
. Поправьте ошибки и повторите запрос. Ключ идемпотентности можно использовать тот же или сгенерировать новый.
Примеры ситуаций, в которых может возвращаться код ответа HTTP 401 при использовании OAuth-авторизации:
- вы не передали OAuth-токен;
- в токене есть опечатки;
- вы удалили приложение, для которого был выдан этот токен;
- токен устарел;
- пользователь отозвал токен.
Причина возникновения ошибки указана в теле ответа, в параметре
description
. Поправьте ошибки, при необходимости получите токен заново и повторите запрос. Ключ идемпотентности можно использовать тот же или сгенерировать новый.
Если запрос корректный, но не хватает прав для совершения операции, API вернет HTTP 403. В теле ответа будет указана возникшая ошибка. Описание параметров тела ответа
Пример ответа
HTTP/2 403
Server: nginx
Date: Wed, 20 Apr 2022 13:55:23 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 281
Signature: v1 29f2248b 1 MGQCMEl6TymNwpekysxE+4ZmSze5gr2MxVolp+ZAZufDN3M+9z4mCQKvCFMQISDqubqQQwIwMr4tLc+QMYA5QnFjwK/YqHC6ESnyb1M/YxcWxpH44UcVHc7Qk6GgEGT2TGMLycbe
{
"type" : "error",
"id" : "17a47682-8d47-4655-a414-a58bdbcd46f9",
"code" : "forbidden",
"description" : "You don't have the rights to send bank card details: you need a PCI DSS certificate and a permission on YooMoney's side. Contact your YooMoney manager to learn more"
}
Примеры ситуаций, когда может возвращаться эта ошибка:
- вы пытаетесь использовать функциональность, которую нужно предварительно согласовывать с менеджером ЮKassa (например, использование автоплатежей в реальном, а не тестовом магазине);
- для OAuth: вы пытаетесь выполнить операцию, для которой не запрашивали права, например если вы изначально выбрали недостаточно прав или сначала получили токен, а затем отредактировали настройки приложения.
Причина возникновения ошибки указана в теле ответа, в параметре
description
. При необходимости тело ответа содержит
parameter
с названием параметра, из-за которого возникла ошибка.
Поправьте ошибки и повторите запрос с новым ключом идемпотентности.
Если запрос корректный, но вы запрашиваете ресурс, которого не существует, API вернет HTTP 404. В теле ответа будет указана возникшая ошибка. Описание параметров тела ответа
Пример ответа
HTTP/2 404
Server: nginx
Date: Thu, 21 Apr 2022 08:09:24 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 254
Signature: v1 29f324f4 1 MGQCMD6EOqWtagcxQ7MkfNGOp2FJ22Gqx1dUGWNJB61lplkAHEkIBy1w7AAFiIBl+wzjJgIwL6ZO07qfziF6wHrGH29nFd1fp4m5L1pO+NXkd8HT8n9TdtPhKn8rfsePd2fLhgvG
{
"type" : "error",
"id" : "cadc8c9c-26bb-417d-829d-261010fac3d5",
"code" : "not_found",
"description" : "Incorrect payment_id. Payment doesn't exist or access denied. Specify the payment ID created in your store.",
"parameter" : "payment_id"
}
Примеры ситуаций, когда может возвращаться эта ошибка:
- вы запрашиваете объект, который создан в одном вашем магазине, а данные для аутентификации используете для другого вашего магазина;
- вы запрашиваете информацию об объекте GET-методом, но в идентификаторе опечатка.
Причина возникновения ошибки указана в теле ответа, в параметре
description
. При необходимости тело ответа содержит
parameter
с названием параметра, из-за которого возникла ошибка.
Поправьте ошибки и повторите запрос с новым ключом идемпотентности.
Если вы используете некорректный HTTP-метод, API вернет HTTP 405.
Пример ответа
HTTP/2 405
Server: nginx
Date: Thu, 21 Apr 2022 08:14:15 GMT
Content-Length: 0
Allow: POST
Reason-Phrase: Request method 'GET' not supported
Signature: v1 29f32617 1 MGQCMA1qpDjDJjRnA7U+2atTebD+czDZLDE10+tD9CPBDIfNlhjJv3oNyDXuBidZRmN+JgIwB7MPYEpQIFebcpJTLMWaRYGqACgKHXCw+jXTsfqciKCvbqDcYdQ5w4XS7mftKGxT
Поправьте HTTP-метод или эндпоинт в зависимости от того, какую операцию вы собираетесь выполнить (подробнее в Справочнике API). Повторите запрос с новым ключом идемпотентности.
Если в запросе указан некорректный тип контента, API вернет HTTP 415.
Пример ответа
HTTP/2 415
Server: nginx
Date: Tue, 12 Apr 2022 15:48:10 GMT
Content-Length: 0
Accept: application/json
Reason-Phrase: Content type 'text/html;charset=utf-8' not supported
Signature: v1 29e7b2fa 1 MGQCMDzQ4/8Z/dPinpHZ53DNekEWgbzrFLvCE5dcseoqbnJhMzUauj0zlUliKJMETcpYMAIwTWHFd49yO7AKyyeNnhUNIFcBBpu4Td875W+h8ndI7kJOutnPC3WJBkTOEvfXpApX
Если передаете тело запроса, данные должны быть в формате JSON. Повторите запрос с новым ключом идемпотентности.
Если от вас будет слишком много запросов в течение короткого промежутка времени, API вернет HTTP 429. В теле ответа будет указана возникшая ошибка. Описание параметров тела ответа
Увеличьте интервалы между запросами, чтобы снизить общее количество обращений за единицу времени.
Пример ответа
HTTP/2 429
Server: nginx
Date: Wed, 20 Apr 2022 14:04:13 GMT
Content-Type: application/json
Content-Length: 199
Signature: v1 29f2269d 1 MGUCMQCJiMvqupFLDI4PY0dLlmVK6WnqagBVCk7OFP0qScRAALdPcFXaZZsmgzf6MSgasjICMAQZGgYdZolt98rlGJfdA/m2J7DqSuzddc1NLrzZv71eLiTYBAI+PHZ6EfyNKISGKA==
{
"type" : "error",
"id" : "2a9ab90e-f69f-4844-980b-4e3ec4ff1c86",
"code" : "too_many_requests",
"description" : "Wow, so many requests! Try to use an exponential backoff of your requests."
}
Если ЮKassa по каким-то причинам не может дать точный ответ на запрос, API вернет HTTP 500. В теле ответа будет указано стандартное описание ошибки без детализации причины. Описание параметров тела ответа
Пример ответа
HTTP/2 500
Server: nginx
Date: Wed, 20 Apr 2022 14:06:10 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 150
Signature: v1 29f22712 1 MGQCMDPcoCj6+TevC0oZqw0S2qnAqq7gOvLSykARc9G1y6qn6YLsmp095OfrAP3qmSgcmgIwMT5A3a/Wnts0tDn7iVQmBZeqMPeg/brYyPIoli/d5myF9VEaP1hvsaAhJRjVPUnW
{
"type" : "error",
"id" : "dd6112e5-9bc8-4382-9f6d-11e9ec39c9c3",
"code" : "internal_server_error",
"description" : "Internal server error"
}
HTTP 500 не говорит об успешности или неуспешности выполнения операции. Например, могут быть ситуации, когда платеж успешно прошел, но ЮKassa по каким-то причинам не смогла сообщить вам результат.
Чтобы узнать окончательный результат, повторите запрос с теми же данными и с тем же ключом идемпотентности или запросите информацию об объекте методом GET. Если ЮKassa снова вернет HTTP 500, повторяйте запрос с возрастающим разумным интервалом (например, можно использовать последовательность Фибоначчи).
Если прошло более получаса, но вы всё еще получаете HTTP 500, обратитесь в техническую поддержку для выяснения окончательного результата выполнения операции.
Неуспешные платежиТестирование платежейВходящие уведомления