Skip to content

Commit dd7d0e0

Browse files
author
morb_au
committedMar 10, 2006
WMS Improvements:
* Errors are now reported as QgsMessageViewer instead of QMessageBox, so that users can copy out URLs - this will be useful for troubleshooting in the field. * Network timeout error reporting now available - timeout set to 120 seconds. * HTTP status code reporting now available - reports anything except codes 200 and 302. WMS Provider Roadmap: * Need to implement the identify() function. * Need to pass the provider object from QgsServerSourceSelect so that it doesn't have to get instatiated twice (and therefore 2 downloads of the GetCapabilities document). git-svn-id: http://svn.osgeo.org/qgis/trunk@4997 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 66c28e4 commit dd7d0e0

File tree

4 files changed

+141
-34
lines changed

4 files changed

+141
-34
lines changed
 

‎src/gui/qgsmapcanvas.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ email : sherman at mrcc.com
2323
#include <QApplication>
2424
#include <QCursor>
2525
#include <QKeyEvent>
26-
#include <QMessageBox>
26+
//#include <QMessageBox>
2727
#include <QMouseEvent>
2828
#include <QPaintDevice>
2929
#include <QPainter>
@@ -48,6 +48,8 @@ email : sherman at mrcc.com
4848
#include "qgsproject.h"
4949
#include "qgsrubberband.h"
5050

51+
#include "qgsmessageviewer.h"
52+
5153
#include "qgsmaptoolzoom.h"
5254
#include "qgsmaptoolpan.h"
5355

@@ -1085,12 +1087,21 @@ void QgsMapCanvas::updateMap()
10851087

10861088
void QgsMapCanvas::showError(QgsMapLayer * mapLayer)
10871089
{
1088-
QMessageBox::warning(
1089-
this,
1090-
mapLayer->errorCaptionString(),
1090+
// QMessageBox::warning(
1091+
// this,
1092+
// mapLayer->errorCaptionString(),
1093+
// tr("Could not draw") + " " + mapLayer->name() + " " + tr("because") + ":\n" +
1094+
// mapLayer->errorString()
1095+
// );
1096+
1097+
QgsMessageViewer * mv = new QgsMessageViewer(this);
1098+
mv->setCaption( mapLayer->errorCaptionString() );
1099+
mv->setMessageAsPlainText(
10911100
tr("Could not draw") + " " + mapLayer->name() + " " + tr("because") + ":\n" +
1092-
mapLayer->errorCaptionString()
1101+
mapLayer->errorString()
10931102
);
1103+
mv->exec();
1104+
delete mv;
10941105

10951106
}
10961107

‎src/gui/qgsserversourceselect.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#include "qgsproject.h"
3030

31+
#include "qgsmessageviewer.h"
32+
3133
#include <QMessageBox>
3234
#include <QPicture>
3335
#include <QSettings>
@@ -579,14 +581,23 @@ void QgsServerSourceSelect::showStatusMessage(QString const & theMessage)
579581

580582
void QgsServerSourceSelect::showError(QgsWmsProvider * wms)
581583
{
582-
QMessageBox::warning(
583-
this,
584-
wms->errorCaptionString(),
584+
// QMessageBox::warning(
585+
// this,
586+
// wms->errorCaptionString(),
587+
// tr("Could not understand the response. The") + " " + wms->name() + " " +
588+
// tr("provider said") + ":\n" +
589+
// wms->errorString()
590+
// );
591+
592+
QgsMessageViewer * mv = new QgsMessageViewer(this);
593+
mv->setCaption( wms->errorCaptionString() );
594+
mv->setMessageAsPlainText(
585595
tr("Could not understand the response. The") + " " + wms->name() + " " +
586-
tr("provider said") + ":\n" +
587-
wms->errorString()
596+
tr("provider said") + ":\n" +
597+
wms->errorString()
588598
);
589-
599+
mv->exec();
600+
delete mv;
590601
}
591602

592603

‎src/providers/wms/qgshttptransaction.cpp

Lines changed: 99 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@
2727
#include <qapplication.h>
2828
#include <q3url.h>
2929

30+
#include <QTimer>
31+
32+
static int NETWORK_TIMEOUT_MSEC = (120 * 1000); // 120 seconds
3033

3134
QgsHttpTransaction::QgsHttpTransaction(QString uri, QString proxyHost, Q_UINT16 proxyPort)
3235
: httpurl(uri),
3336
httphost(proxyHost),
3437
httpport(proxyPort),
35-
httpresponsecontenttype(0)
38+
httpresponsecontenttype(0),
39+
mError(0)
3640
{
3741
#ifdef QGISDEBUG
3842
std::cout << "QgsHttpTransaction: constructing." << std::endl;
@@ -87,40 +91,49 @@ bool QgsHttpTransaction::getSynchronously(QByteArray &respondedContent, int redi
8791
// Proxy -> send complete URL
8892
path = httpurl;
8993
}
90-
http = new Q3Http( httphost, httpport );
94+
http = new Q3Http( httphost, httpport );
95+
mWatchdogTimer = new QTimer( this );
9196

9297
#ifdef QGISDEBUG
9398
qWarning("QgsHttpTransaction::getSynchronously: qurl.host() is '"+qurl.host()+ "'.");
9499
qWarning("QgsHttpTransaction::getSynchronously: qurl.encodedPathAndQuery() is '"+qurl.encodedPathAndQuery()+"'.");
95100
std::cout << "path = " << path.ascii() << std::endl;
96101
#endif
97-
102+
98103
httpresponse.truncate(0);
99104
httpid = http->get( path );
100-
httpactive = TRUE;
101-
102-
connect(http, SIGNAL( requestStarted ( int ) ),
105+
106+
connect(http, SIGNAL( requestStarted ( int ) ),
103107
this, SLOT( dataStarted ( int ) ) );
104-
105-
connect(http, SIGNAL( responseHeaderReceived( const Q3HttpResponseHeader& ) ),
108+
109+
connect(http, SIGNAL( responseHeaderReceived( const Q3HttpResponseHeader& ) ),
106110
this, SLOT( dataHeaderReceived( const Q3HttpResponseHeader& ) ) );
107-
108-
connect(http, SIGNAL( readyRead( const Q3HttpResponseHeader& ) ),
111+
112+
connect(http, SIGNAL( readyRead( const Q3HttpResponseHeader& ) ),
109113
this, SLOT( dataReceived( const Q3HttpResponseHeader& ) ) );
110-
111-
connect(http, SIGNAL( dataReadProgress ( int, int ) ),
114+
115+
connect(http, SIGNAL( dataReadProgress ( int, int ) ),
112116
this, SLOT( dataProgress ( int, int ) ) );
113117

114-
connect(http, SIGNAL( requestFinished ( int, bool ) ),
118+
connect(http, SIGNAL( requestFinished ( int, bool ) ),
115119
this, SLOT( dataFinished ( int, bool ) ) );
116120

117-
connect(http, SIGNAL( stateChanged ( int ) ),
121+
connect(http, SIGNAL( stateChanged ( int ) ),
118122
this, SLOT( dataStateChanged ( int ) ) );
119123

124+
// Set up the watchdog timer
125+
connect(mWatchdogTimer, SIGNAL( timeout () ),
126+
this, SLOT( networkTimedOut () ) );
127+
128+
mWatchdogTimer->setSingleShot(TRUE);
129+
mWatchdogTimer->start(NETWORK_TIMEOUT_MSEC);
130+
120131
#ifdef QGISDEBUG
121132
std::cout << "QgsHttpTransaction::getSynchronously: Starting get." << std::endl;
122133
#endif
123134

135+
httpactive = TRUE;
136+
124137
// A little trick to make this function blocking
125138
while ( httpactive )
126139
{
@@ -132,14 +145,22 @@ bool QgsHttpTransaction::getSynchronously(QByteArray &respondedContent, int redi
132145

133146
#ifdef QGISDEBUG
134147
std::cout << "QgsHttpTransaction::getSynchronously: Response received." << std::endl;
135-
148+
136149
// QString httpresponsestring(httpresponse);
137150
// std::cout << "QgsHttpTransaction::getSynchronously: Response received; being '" << httpresponsestring << "'." << std::endl;
138151
#endif
139-
140152

141153
delete http;
142154

155+
// Did we get an error? If so, bail early
156+
if (!mError.isNull())
157+
{
158+
#ifdef QGISDEBUG
159+
std::cout << "QgsHttpTransaction::getSynchronously: Processing an error '" << mError.toLocal8Bit().data() << "'." << std::endl;
160+
#endif
161+
return FALSE;
162+
}
163+
143164
// Do one level of redirection
144165
// TODO make this recursable
145166
// TODO detect any redirection loops
@@ -195,15 +216,28 @@ void QgsHttpTransaction::dataHeaderReceived( const Q3HttpResponseHeader& resp )
195216
resp.value("Content-Type").toLocal8Bit().data() << "'." << std::endl;
196217
#endif
197218

219+
// We saw something come back, therefore restart the watchdog timer
220+
mWatchdogTimer->start(NETWORK_TIMEOUT_MSEC);
221+
198222
if (resp.statusCode() == 302) // Redirect
199223
{
200224
// Grab the alternative URL
201225
// (ref: "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html")
202226
httpredirecturl = resp.value("Location");
203227
}
228+
else if (resp.statusCode() == 200) // OK
229+
{
230+
// NOOP
231+
}
232+
else
233+
{
234+
mError = QString( tr("WMS Server responded unexpectedly with HTTP Status Code %1 (%2)") )
235+
.arg( resp.statusCode() )
236+
.arg( resp.reasonPhrase() );
237+
}
204238

205239
httpresponsecontenttype = resp.value("Content-Type");
206-
240+
207241
}
208242

209243

@@ -224,7 +258,7 @@ void QgsHttpTransaction::dataReceived( const Q3HttpResponseHeader& resp )
224258
// std::cout << "QgsHttpTransaction::dataReceived." << std::endl;
225259
// std::cout << "QgsHttpTransaction::dataReceived: received '" << data << "'."<< std::endl;
226260
#endif
227-
261+
228262
}
229263

230264

@@ -235,6 +269,9 @@ void QgsHttpTransaction::dataProgress( int done, int total )
235269
// std::cout << "QgsHttpTransaction::dataProgress: got " << done << " of " << total << std::endl;
236270
#endif
237271

272+
// We saw something come back, therefore restart the watchdog timer
273+
mWatchdogTimer->start(NETWORK_TIMEOUT_MSEC);
274+
238275
QString status;
239276

240277
if (total)
@@ -258,11 +295,30 @@ void QgsHttpTransaction::dataFinished( int id, bool error )
258295
#ifdef QGISDEBUG
259296
std::cout << "QgsHttpTransaction::dataFinished with ID " << id << "." << std::endl;
260297

298+
// The signal that this slot is connected to, Q3Http::requestFinished,
299+
// appears to get called at the destruction of the Q3Http if it is
300+
// still working at the time of the destruction.
301+
//
302+
// This situation may occur when we've detected a timeout and
303+
// we already set httpactive = FALSE.
304+
//
305+
// We have to detect this special case so that the last known error string is
306+
// not overwritten (it should rightfully refer to the timeout event).
307+
if (!httpactive)
308+
{
309+
std::cout << "QgsHttpTransaction::dataFinished - http activity loop already FALSE." << std::endl;
310+
return;
311+
}
312+
261313
if (error)
262314
{
263315
std::cout << "QgsHttpTransaction::dataFinished - however there was an error." << std::endl;
264316
std::cout << "QgsHttpTransaction::dataFinished - " << http->errorString().toLocal8Bit().data() << std::endl;
265-
} else
317+
318+
mError = QString( tr("HTTP response completed, however there was an error: %1") )
319+
.arg( http->errorString() );
320+
}
321+
else
266322
{
267323
std::cout << "QgsHttpTransaction::dataFinished - no error." << std::endl;
268324
}
@@ -272,7 +328,7 @@ void QgsHttpTransaction::dataFinished( int id, bool error )
272328
httpresponse = http->readAll();
273329

274330
httpactive = FALSE;
275-
331+
276332
}
277333

278334
void QgsHttpTransaction::dataStateChanged( int state )
@@ -282,6 +338,9 @@ void QgsHttpTransaction::dataStateChanged( int state )
282338
std::cout << "QgsHttpTransaction::dataStateChanged to " << state << "." << std::endl << " ";
283339
#endif
284340

341+
// We saw something come back, therefore restart the watchdog timer
342+
mWatchdogTimer->start(NETWORK_TIMEOUT_MSEC);
343+
285344
switch (state)
286345
{
287346
case Q3Http::Unconnected:
@@ -350,6 +409,26 @@ void QgsHttpTransaction::dataStateChanged( int state )
350409
}
351410

352411

412+
void QgsHttpTransaction::networkTimedOut()
413+
{
414+
415+
#ifdef QGISDEBUG
416+
std::cout << "QgsHttpTransaction::networkTimedOut: entering." << std::endl;
417+
#endif
418+
419+
mError = QString(tr("Network timed out after %1 seconds of inactivity.\n"
420+
"This may be a problem in your network connection or at the WMS server.")
421+
).arg(NETWORK_TIMEOUT_MSEC/1000);
422+
423+
httpactive = FALSE;
424+
425+
#ifdef QGISDEBUG
426+
std::cout << "QgsHttpTransaction::networkTimedOut: exiting." << std::endl;
427+
#endif
428+
429+
}
430+
431+
353432
QString QgsHttpTransaction::errorString()
354433
{
355434
return mError;

‎src/providers/wms/qgshttptransaction.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ class QgsHttpTransaction : public QObject
7878
public slots:
7979

8080
void dataStarted( int id );
81-
81+
8282
void dataHeaderReceived( const Q3HttpResponseHeader& resp );
83-
83+
8484
void dataReceived( const Q3HttpResponseHeader& resp );
8585

8686
void dataProgress( int done, int total );
@@ -89,7 +89,8 @@ public slots:
8989

9090
void dataStateChanged( int state );
9191

92-
92+
void networkTimedOut();
93+
9394
signals:
9495

9596
/** \brief emit a signal to notify of a progress event */
@@ -160,6 +161,11 @@ public slots:
160161
*/
161162
int httpredirections;
162163

164+
/**
165+
* Indicates the associated QTimer object - used to detect network timeouts
166+
*/
167+
QTimer * mWatchdogTimer;
168+
163169
/**
164170
* The error message associated with the last HTTP error.
165171
*/

0 commit comments

Comments
 (0)