From d074ce286f656c5e6041fb5e0152bb9ce3547ae9 Mon Sep 17 00:00:00 2001 From: Sophist Date: Mon, 24 Feb 2014 10:15:20 +0000 Subject: [PATCH] Handle network errors better 1. Process network error instead of response 2. Error message on redirect loop 3. In both of the above call handler to avoid Loading Album message being stuck. Received the following error when coverart was temp unavail: D: 09:25:27 GET http://archive.org:80/download/mbid-8028cf3c-fcf5-4915-ae47-ca29b2875d64/index.json Traceback (most recent call last): File ".\picard\webservice.py", line 240, in _process_reply cached File ".\picard\log.py", line 81, in debug main_logger.message(LOG_DEBUG, message, *args) File ".\picard\log.py", line 58, in message message = message % args TypeError: %d format: a number is required, not NoneType --- picard/webservice.py | 98 ++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/picard/webservice.py b/picard/webservice.py index aae18cdf7..4d72c410d 100644 --- a/picard/webservice.py +++ b/picard/webservice.py @@ -230,52 +230,60 @@ class XmlWebService(QtCore.QObject): log.error("Request not found for %s" % reply.request().url().toString(QUrl.RemoveUserInfo)) return error = int(reply.error()) - redirect = reply.attribute(QtNetwork.QNetworkRequest.RedirectionTargetAttribute) - fromCache = reply.attribute(QtNetwork.QNetworkRequest.SourceIsFromCacheAttribute) - cached = ' (CACHED)' if fromCache else '' - log.debug("Received reply for %s: HTTP %d (%s) %s", - reply.request().url().toString(QUrl.RemoveUserInfo), - reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute), - reply.attribute(QtNetwork.QNetworkRequest.HttpReasonPhraseAttribute), - cached - ) - if handler is not None: - if error: - log.error("Network request error for %s: %s (QT code %d, HTTP code %d)", - reply.request().url().toString(QUrl.RemoveUserInfo), - reply.errorString(), - error, - reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)) - - # Redirect if found and not infinite - if redirect and not XmlWebService.urls_equivalent(redirect, reply.request().url()): - log.debug("Redirect to %s requested", redirect.toString(QUrl.RemoveUserInfo)) - redirect_host = str(redirect.host()) - redirect_port = redirect.port(80) - - url = request.url() - original_host = str(url.host()) - original_port = url.port(80) - - if ((original_host, original_port) in REQUEST_DELAY - and (redirect_host, redirect_port) not in REQUEST_DELAY): - log.debug("Setting rate limit for %s:%i to %i" % - (redirect_host, redirect_port, - REQUEST_DELAY[(original_host, original_port)])) - REQUEST_DELAY[(redirect_host, redirect_port)] =\ - REQUEST_DELAY[(original_host, original_port)] - - self.get(redirect_host, - redirect_port, - # retain path, query string and anchors from redirect URL - redirect.toString(QUrl.RemoveAuthority | QUrl.RemoveScheme), - handler, xml, priority=True, important=True, refresh=refresh, - cacheloadcontrol=request.attribute(QtNetwork.QNetworkRequest.CacheLoadControlAttribute)) - elif xml: - document = _read_xml(QXmlStreamReader(reply)) - handler(document, reply, error) - else: + if error: + log.error("Network request error for %s: %s (QT code %d, HTTP code %s)", + reply.request().url().toString(QUrl.RemoveUserInfo), + reply.errorString(), + error, + repr(reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)) + ) + if handler is not None: handler(str(reply.readAll()), reply, error) + else: + redirect = reply.attribute(QtNetwork.QNetworkRequest.RedirectionTargetAttribute) + fromCache = reply.attribute(QtNetwork.QNetworkRequest.SourceIsFromCacheAttribute) + cached = ' (CACHED)' if fromCache else '' + log.debug("Received reply for %s: HTTP %d (%s) %s", + reply.request().url().toString(QUrl.RemoveUserInfo), + reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute), + reply.attribute(QtNetwork.QNetworkRequest.HttpReasonPhraseAttribute), + cached + ) + if handler is not None: + # Redirect if found and not infinite + if redirect and not XmlWebService.urls_equivalent(redirect, reply.request().url()): + log.debug("Redirect to %s requested", redirect.toString(QUrl.RemoveUserInfo)) + redirect_host = str(redirect.host()) + redirect_port = redirect.port(80) + + url = request.url() + original_host = str(url.host()) + original_port = url.port(80) + + if ((original_host, original_port) in REQUEST_DELAY + and (redirect_host, redirect_port) not in REQUEST_DELAY): + log.debug("Setting rate limit for %s:%i to %i" % + (redirect_host, redirect_port, + REQUEST_DELAY[(original_host, original_port)])) + REQUEST_DELAY[(redirect_host, redirect_port)] =\ + REQUEST_DELAY[(original_host, original_port)] + + self.get(redirect_host, + redirect_port, + # retain path, query string and anchors from redirect URL + redirect.toString(QUrl.RemoveAuthority | QUrl.RemoveScheme), + handler, xml, priority=True, important=True, refresh=refresh, + cacheloadcontrol=request.attribute(QtNetwork.QNetworkRequest.CacheLoadControlAttribute)) + elif redirect: + log.error("Redirect loop: %s", + reply.request().url().toString(QUrl.RemoveUserInfo) + ) + handler(str(reply.readAll()), reply, error) + elif xml: + document = _read_xml(QXmlStreamReader(reply)) + handler(document, reply, error) + else: + handler(str(reply.readAll()), reply, error) reply.close() self.num_pending_web_requests -= 1 self.tagger.tagger_stats_changed.emit()