- 1. QNetworkReply::ConnectionRefusedError и QNetworkReply::RemoteHostClosedError
- 2. QNetworkReply::HostNotFoundError
- 3. QNetworkReply::TimeoutError
- 4. QNetworkReply::OperationCanceledError
- 5. QNetworkReply::SslHandshakeFailedError
- 6. QNetworkReply::TemporaryNetworkFailureError и QNetworkReply::NetworkSessionFailedError
- 7. QNetworkReply::BackgroundRequestNotAllowedError
- 8. QNetworkReply::TooManyRedirectsError и QNetworkReply::InsecureRedirectError
- 9. Ошибки QNetworkReply::Proxy*
- 10. QNetworkReply::ContentAccessDenied
- 11. QNetworkReply::AuthenticationRequiredError
- 12. QNetworkReply::ContentReSendError
- 13. QNetworkReply::ContentConflictError
- 14. QNetworkReply::ContentGoneError
- 15. QNetworkReply::InternalServerError
- 16. QNetworkReply::OperationNotImplementedError
- 17. QNetworkReply::ProtocolUnknownError
- 18. QNetworkReply::ServiceUnavailableError
- 19. QNetworkReply::ProtocolInvalidOperationError
- 20. QNetworkReply::UnknownNetworkError
- 21. QNetworkReply::UnknownProxyError
- 22. Ошибки QNetworkReply::UnknownContentError,QNetworkReply::ProtocolFailure, QNetworkReply::UnknownServerError
- 23. Пример с выводом ошибки в qDebug
В одном из уроков была представлена работа с QNetworkAccessManager для получения содержимого страницы с сайта по протоколу http. Там была сделана проверка на наличие ошибок, но не были даны пояснения, какие могут быть ошибки. Для этого класс QNetworkReply предоставляет enum NetworkError , в котором перечислены коды возможных ошибок.
В случае успешного выполнения возвращается NoError , равный 0 .
В противном случае возвращается код ошибки из кодов, представленных ниже:
Константа | Значение | Описание |
---|---|---|
QNetworkReply::ConnectionRefusedError | 1 | Удалённый сервер отклонил соединение (сервер не принимает запросы) |
QNetworkReply::RemoteHostClosedError | 2 | удаленный сервер закрыл соединение преждевременно, до того, как весь ответ был получен и обработан |
QNetworkReply::HostNotFoundError | 3 | удаленный хост не был найден (недействительное имя хоста) |
QNetworkReply::TimeoutError | 4 | подключение к удаленному серверу истекло |
QNetworkReply::OperationCanceledError | 5 | операция была отменена через вызов abort() или close() до того, как была завершена. |
QNetworkReply::SslHandshakeFailedError | 6 | Подключение по SSL/TLS не удалось, шифрованный канал не может быть. Должен испускаться сигнал sslErrors(). |
QNetworkReply::TemporaryNetworkFailureError | 7 | соединение было нарушено из-за отключения от сети, однако система инициировала роуминг к другой точке доступа. Запрос должен быть повторно и будет обработан, как только соединение будет восстановлено. |
QNetworkReply::NetworkSessionFailedError | 8 | соединение было нарушено из-за отключения от сети или невозможности запуска сети. |
QNetworkReply::BackgroundRequestNotAllowedError | 9 | запрос в настоящее время не допускается из-за политики платформы. |
QNetworkReply::TooManyRedirectsError | 10 | количество редиректов превысило допустимый лимит. Лимит по умолчанию установлен на 50 редиректов через QNetworkRequest::setMaxRedirectsAllowed(). |
QNetworkReply::InsecureRedirectError | 11 | во время обработки редиректов, API доступа по сети обнаружило редирект с шифрованного протокола (https) на не шифрованный (http) |
QNetworkReply::ProxyConnectionRefusedError | 101 | в подключении к прокси-серверу было отказано (прокси-сервер не принимает запросы) |
QNetworkReply::ProxyConnectionClosedError | 102 | прокси-сервер закрыл соединение преждевременно, до того, как весь ответ был получен и обработан |
QNetworkReply::ProxyNotFoundError | 103 | прокси-хост не был найден (недействительное имя прокси хоста) |
QNetworkReply::ProxyTimeoutError | 104 | подключение к прокси-серверу истекло или прокси-сервер не ответил вовремя на отправленный запрос |
QNetworkReply::ProxyAuthenticationRequiredError | 105 | прокси-сервер требует аутентификации для того, чтобы удовлетворить запрос, но не принял каких-либо предложенных учётных данных (если таковые имеются) |
QNetworkReply::ContentAccessDenied | 201 | в доступе к удаленному контенту было отказано (по аналогии с ошибкой HTTP 401) |
QNetworkReply::ContentOperationNotPermittedError | 202 | Запрошенная операция на удаленное содержимое не допускается |
QNetworkReply::ContentNotFoundError | 203 | удаленный контент не был найден на сервере (аналогично ошибке HTTP 404) |
QNetworkReply::AuthenticationRequiredError | 204 | удаленный сервер требует аутентификации, чтобы предоставить контент, но предоставленные учетные данные не были приняты (если таковые имеются) |
QNetworkReply::ContentReSendError | 205 | запрос необходимо отправить повторно, но это не удалось, например, потому что загрузка данных не может быть прочитана во второй раз. |
QNetworkReply::ContentConflictError | 206 | запрос не может быть завершен из-за конфликта с текущим состоянием ресурса. |
QNetworkReply::ContentGoneError | 207 | запрошенный ресурс больше не доступен на сервере. |
QNetworkReply::InternalServerError | 401 | Сервер столкнулся с непредвиденным условием, которое не позволяет ему выполнить запрос. |
QNetworkReply::OperationNotImplementedError | 402 | сервер не поддерживает функциональные возможности, необходимые для выполнения запроса. |
QNetworkReply::ServiceUnavailableError | 403 | сервер не может обработать запрос в данный момент. |
QNetworkReply::ProtocolUnknownError | 301 | Network Access API не может удовлетворить запрос, потому что протокол не известен |
QNetworkReply::ProtocolInvalidOperationError | 302 | запрошенная операция недопустима для этого протокола |
QNetworkReply::UnknownNetworkError | 99 | была обнаружена неизвестная ошибка сети |
QNetworkReply::UnknownProxyError | 199 | была обнаружена неизвестная ошибка прокси |
QNetworkReply::UnknownContentError | 299 | была обнаружена неизвестная ошибка, связанная с удаленным содержимым |
QNetworkReply::ProtocolFailure | 399 | был обнаружен сбой в протоколе (ошибка синтаксического анализа, недействительные или неожиданные ответы и т.д.) |
QNetworkReply::UnknownServerError | 499 | была обнаружена неизвестная ошибка, связанная с ответом сервера |
После изучения данного списка ошибок можно сделать вывод, что данный список объединяет в себе значительно больший список ошибок, чем, например, тот список кодов ошибок, который может вернуть http сервер. Давайте поговорим немного о возможных ошибках и из-за чего они могут возникнуть.
QNetworkReply::ConnectionRefusedError и QNetworkReply::RemoteHostClosedError
Если говорить об интерпретации данных ошибок, то наиболее ярким примером для меня является подключение по SSH к другому хосту. Смысл ошибок в том, что в первом случае сервер нас не пускает, а во втором случае соединение могло быть закрыто по истечению определённого периода времени.
Также ошибка ConnectionRefusedError может возникать в случаях, когда на определённом порту ПК просто нет службы, которая могла бы обработать запрос.
QNetworkReply::HostNotFoundError
Пожалуй довольно понятная ошибка, которая обозначает, что вы просто ввели неверный ip адрес или домен, с которого пытаетесь получить данные. Также, такая ошибка может возникнуть в том случае, если домен перестал быть доступен в сети. Данная ошибка аналогична ошибке номер 105 - ERR_NAME_NOT_RESOLVED (HTTP).
QNetworkReply::TimeoutError
Превышен интервал ожидания. Наиболее близкое сравнение - это использование протокола ICMP, проверка доступности узла в сети, когда производим его ping. То есть узел в сети вроде бы и есть, но он не отвечает.
QNetworkReply::OperationCanceledError
А вот ошибка, которая будет относится уже к действиям самой программы на Qt. В данном случае она будет возникать тогда, когда логика программы прерывает получение данных через QNetworkAccessManager. То есть данная ошибка не должна возникать в том случае, если операция получения данных была прервана извне. Поэтому, если Вы отлавливаете подобную ошибку, то ищите проблему внутри вашей собственной программы.
QNetworkReply::SslHandshakeFailedError
Для установления шифрованных каналов связи, которые используют SSL шифрование, требуется установка соединения через операции квитирования, то есть через подтверждение приёма/передачи информации. В данном случае осуществляется согласование параметров шифрования, передача сеансового ключа, а также необязательные операции аутентификации сервера клиентом и клиента сервером. Если что-то из перечисленного пойдёт не так, то будет выброшена данная ошибка.
QNetworkReply::TemporaryNetworkFailureError и QNetworkReply::NetworkSessionFailedError
Возникновение данных ошибок может быть вызвано любой неполадкой в сети вплоть до падения физического подключения к сети. Проверять подключения можно через класс QNetworkInterface.
Класс
QNetworkInterface
имеет статический метод
QList
Поэтому, чтобы понять, что не так, при получении ошибок QNetworkReply::TemporaryNetworkFailureErro r и QNetworkReply::NetworkSessionFailedError придётся протестировать интерфейсы ПК на предмет активности: QNetworkInterface::IsUp и QNetworkInterface::IsRunning.
QNetworkReply::BackgroundRequestNotAllowedError
А вот эта ошибка зависит непосредственно от политик платформы, для которой разрабатывается приложение. Например, если под некоторым абстрактным Android устройством запрещён обмен информацией по сети в энергосберегающем режиме, то в данном режиме мы будем получать именно эту ошибку, при попытке обмена информацией.
QNetworkReply::TooManyRedirectsError и QNetworkReply::InsecureRedirectError
А вот эти ошибки из разряда новенького в Qt 5.6. Теперь можно отслеживать превышения количества редиректов со страниц сайтов, а также редиректы со страниц с шифрованием https на страницы без шифрования. Что может быть полезно для разработки программного обеспечения для анализа сайтов.
Без дополнительных настроек данные ошибки как правило не возникают. Дело в том, что когда задаётся QNetworkRequest и в него не устанавливаются флаги конфигурации, то при попытке запроса страницы с сайта, с которой осуществляется редирект, не будет происходить перехода на новый url, а в QNetworkReply не будет никакого полезного контента. Поэтому потребуется установить в QNetworkRequest флаг QNetworkRequest::FollowRedirectsAttribute, тогда QNetworkAccessManager будет переходить по редиректам, пока не получит итоговую страницу или не превысит ограничение на количество переходов. По умолчанию количество переходов ограничено 50-ю.
Установка атрибута может производиться следующим образом:
QNetworkRequest request; request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, QVariant(true));
Что касается QNetworkReply::InsecureRedirectError, то смысл заключается в том, чтобы отследить редирект на небезопасный протокол.
Ошибки QNetworkReply::Proxy*
Следующие пять ошибок аналогичны по своему характеру ошибкам подключения к серверам без проксирования.
QNetworkReply::ContentAccessDenied
В документации сказано, что данная ошибка аналогична ошибке 401 в HTTP, то есть требуется авторизация, но полагаю, что данная ошибка может возникать и в случаях получения кода 403 и 407. Ошибка 407 аналогична ошибке 401, но используется для прокси-сервера. А ошибка 403 является порождающей для ошибок 401 и 407.
QNetworkReply::AuthenticationRequiredError
Данная ошибка характерна для HTTP протокола. Дело в том, что http протокол поддерживает схемы проверки подлинности. В данном случае необходимо посылать запрос на сервер с установкой логина и пароля. Замечу, что это напрямую означает то, что Вы можете написать приложение на Qt, которое будет аутентифицироваться на сайтах и выполнять определённые действия на сайте уже в авторизованном режиме, то есть можно написать и бота для работы на сайте.
Решение проблемы заключается в том, чтобы установить логин и пароль пользователя в QAuthenticator, который будет подмешивать учётные данные к запросу. Причем делаться это будет в автоматическом режиме по сигналу QNetworkAccessManager::authenticationRequired, при этом логин и пароль будут кешированы, так что сигнал не будет испускаться при каждом запросе.
connect(&m_manager,&QNetworkAccessManager::authenticationRequired, [this](QNetworkReply *rep, QAuthenticator* auth){ auth->setUser("username"); auth->setPassword("passwordd"); });
QNetworkReply::ContentReSendError
Провести какую-либо точную аналогию с кодами HTTP для этой ошибки является затруднительным, поскольку вызываться она может различными причинами.
QNetworkReply::ContentConflictError
Данная ошибка соответствует ошибке 409 Confilct в протоколе HTTP.
QNetworkReply::ContentGoneError
Данная ошибка соответствует ошибке 410 Gone (Удалён) в протоколе HTTP.
QNetworkReply::InternalServerError
Данная ошибка соответствует ошибке 500 Internal Server Error (Внутренняя ошибка сервера) в протоколе http.
QNetworkReply::OperationNotImplementedError
Данная ошибка соответствует ошибке 501 Not Implemented (Не реализовано) в протоколе http. Возникает такая тогда, когда Вы пытаетесь выполнить, например, запрос POST к URL, по которому сервер обрабатывает только GET запросы.
Такое поведение можно встретить, например, в Django проекте. Если запрос не реализован, то сервер с Django отправит пустую страницу на POST запрос с данным кодом.
QNetworkReply::ProtocolUnknownError
Такая ошибка, как QNetworkReply::ProtocolUnknownError, может возникнуть из-за того, что в запрос был передан url без указания типа протокола, то есть вместо
http://www.example.com
было передано
//www.example.com
Такая проблема может возникнуть в том случае, если вы парсите страницы и извлекаете url изображений. Например, на данном сайте адреса всех изображений в статьях выглядят следующим образом
/media/uploads/2017/02/03/testquickwidget.jpg
То есть не указывается протокол и домен сайта. Поэтому если Вы извлечёте все адреса изображений со страницы, то не сможете скачать изображения без дополнительной обработки, а именно без подстановки домена и протокола в начале строки, получив данную ошибку.
QNetworkReply::ServiceUnavailableError
Соответствует ошибке 503 Service Unavailable («сервис недоступен») в протоколе http
QNetworkReply::ProtocolInvalidOperationError
В данном случае протокол определён, но точное соответствие ошибке из протокола http не прослеживается, относительно других протоколов также может быть что угодно.
QNetworkReply::UnknownNetworkError
Наиболее частый вариант того, чему может соответствовать данная ошибка является ошибка шлюза 502 Bad Gateway («плохой, ошибочный шлюз») в протоколу http
QNetworkReply::UnknownProxyError
Также может быть ошибка 502, но уже в варианте с прокси-сервером
Ошибки QNetworkReply::UnknownContentError,QNetworkReply::ProtocolFailure, QNetworkReply::UnknownServerError
С данными ошибками затрудняюсь найти рабочее соответствие, буду рад подсказке, если кто сталкивался.
Пример с выводом ошибки в qDebug
Можно проверять ошибку по сигналу завершения запроса от QNetworkAccessManager в слоте, который подключается для обработки результата запроса.
manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, this, &Downloader::onResult);
В данном случае имеется класс-обёртка над классом QNetworkAccessManager с названием Downloader . У этого класса имеется слот onResult , который в свою очередь отвечает за обработку результата ответа QNetworkAccessManager .
void Downloader::onResult(QNetworkReply *reply) { // Если в процессе получения данных произошла ошибка if(reply->error()){ // Сообщаем об этом и показываем информацию об ошибках qDebug() << "ERROR"; // Здесь получаем один из enum NetworkError, то есть код ошибки qDebug() << reply->error(); } else { // ToDo something } }
Unable to init SSL Context: Выдает приложение, что это может быть?
OpenSSL библиотеки возможно требуются. В этой статье есть ссылки, где скачать библиотеки OpenSSL.