- 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 .
В противном случае возвращается код ошибки из кодов, представленных ниже:
Константа | Значение | Описание |
---|---|---|
|
| Удалённый сервер отклонил соединение (сервер не принимает запросы) |
|
| удаленный сервер закрыл соединение преждевременно, до того, как весь ответ был получен и обработан |
|
| удаленный хост не был найден (недействительное имя хоста) |
|
| подключение к удаленному серверу истекло |
|
| операция была отменена через вызов abort() или close() до того, как была завершена. |
|
| Подключение по SSL/TLS не удалось, шифрованный канал не может быть. Должен испускаться сигнал sslErrors(). |
|
| соединение было нарушено из-за отключения от сети, однако система инициировала роуминг к другой точке доступа. Запрос должен быть повторно и будет обработан, как только соединение будет восстановлено. |
|
| соединение было нарушено из-за отключения от сети или невозможности запуска сети. |
|
| запрос в настоящее время не допускается из-за политики платформы. |
|
| количество редиректов превысило допустимый лимит. Лимит по умолчанию установлен на 50 редиректов через QNetworkRequest::setMaxRedirectsAllowed(). |
|
| во время обработки редиректов, API доступа по сети обнаружило редирект с шифрованного протокола (https) на не шифрованный (http) |
|
| в подключении к прокси-серверу было отказано (прокси-сервер не принимает запросы) |
|
| прокси-сервер закрыл соединение преждевременно, до того, как весь ответ был получен и обработан |
|
| прокси-хост не был найден (недействительное имя прокси хоста) |
|
| подключение к прокси-серверу истекло или прокси-сервер не ответил вовремя на отправленный запрос |
|
| прокси-сервер требует аутентификации для того, чтобы удовлетворить запрос, но не принял каких-либо предложенных учётных данных (если таковые имеются) |
|
| в доступе к удаленному контенту было отказано (по аналогии с ошибкой HTTP 401) |
|
| Запрошенная операция на удаленное содержимое не допускается |
|
| удаленный контент не был найден на сервере (аналогично ошибке HTTP 404) |
|
| удаленный сервер требует аутентификации, чтобы предоставить контент, но предоставленные учетные данные не были приняты (если таковые имеются) |
|
| запрос необходимо отправить повторно, но это не удалось, например, потому что загрузка данных не может быть прочитана во второй раз. |
|
| запрос не может быть завершен из-за конфликта с текущим состоянием ресурса. |
|
| запрошенный ресурс больше не доступен на сервере. |
|
| Сервер столкнулся с непредвиденным условием, которое не позволяет ему выполнить запрос. |
|
| сервер не поддерживает функциональные возможности, необходимые для выполнения запроса. |
|
| сервер не может обработать запрос в данный момент. |
|
| Network Access API не может удовлетворить запрос, потому что протокол не известен |
|
| запрошенная операция недопустима для этого протокола |
|
| была обнаружена неизвестная ошибка сети |
|
| была обнаружена неизвестная ошибка прокси |
|
| была обнаружена неизвестная ошибка, связанная с удаленным содержимым |
|
| был обнаружен сбой в протоколе (ошибка синтаксического анализа, недействительные или неожиданные ответы и т.д.) |
|
| была обнаружена неизвестная ошибка, связанная с ответом сервера |
После изучения данного списка ошибок можно сделать вывод, что данный список объединяет в себе значительно больший список ошибок, чем, например, тот список кодов ошибок, который может вернуть 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.