In my Console Project I have 4 functions: Response
, AddDataToList
, Request
and main
.
In main
function chars
is a Vector containing characters a-z. manager
, doc
, array
and list
are variables to be used in Request
function along with the elements of chars
. In the first for
loop a single character (eg. a,b,c,…,z) from chars
is passed to Request
and in the following nested for
loop two characters (eg. aa,ab,ac,…,zz) are passed to Request
.
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<char> chars;
for (int i = 97; i < 123; i++) chars.push_back((char)i);
QNetworkAccessManager manager;
QJsonDocument doc;
QJsonArray array;
QVector<QString> list;
int count = chars.count();
for (int i = 0; i < count; i++) {
Request(manager, QString(chars[i]), doc, array, list);
for (int j = 0; j < count; j++)
Request(manager, QString("%1%2").arg(chars[i]).arg(chars[j]), doc, array, list);
}
qDebug() << "Total: " + QString::number(list.count());
return a.exec();
}
In Request
those characters are used as querystring
in the url
that is passed to Response
function to get json array
and each element of array
is then added to the Vector named list
in AddDataToList
function.
void Request(QNetworkAccessManager &manager, QString &queryString,
QJsonDocument &doc, QJsonArray &array, QVector<QString> &list)
{
QUrl url =QString("http://www.icab.org.bd/icabweb/firmCompanyAudited/geJsonAuditedFirm?term=%1").arg(queryString);
Response(manager.get(QNetworkRequest(url)), doc, array);
AddDataToList(list, array);
}
void Response(QNetworkReply *reply, QJsonDocument &doc, QJsonArray& array)
{
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
doc = QJsonDocument::fromJson(reply->readAll());
delete reply;
array = doc.array();
}
void AddDataToList(QVector<QString> &list, QJsonArray &array)
{
int count = array.count();
for (int n = 0; n < count; n++) list.append(array[n].toString());
}
Last line of the main
writes the number of elements in the list
and I expected to get same number each time it runs, but the number was:
19793, 19703, 19791, etc.
reply->error()
always gives NoError
.
Where is the problem?
EDIT:
I also have written equivalent code in C# where I had to use Newtonsoft.Json
's DeserializeObject
method in a try-catch
in order to complete the loop. Result of 5 consecutive test sessions was:
Test Session: 0
19793 item found
0 item in error List
====================================================
Test Session: 1
ev : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
yy : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
19743 item found
2 item in error List
====================================================
Test Session: 2
cm : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
jv : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
nl : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
19737 item found
3 item in error List
====================================================
Test Session: 3
uk : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
19743 item found
1 item in error List
====================================================
Test Session: 4
lk : Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
19768 item found
1 item in error List
====================================================
May I get somewhat similar error in my Qt
Response
function when I call:
QJsonDocument::fromJson(reply->readAll())
or doc.array()
?
I guess the problem is in doc = QJsonDocument::fromJson(reply->readAll())
. It assigns <html>
in doc
in some cases.
Why does it send <html>
instead of json
?
I got curious about your problem and added your code to my test application.
I needed to do one change to get you code compiled with gcc. You were passing temporary object as a query string. Add const to QString &queryString
in Request function. I guess you are using MS compiler which is not as strict with this...
error: invalid initialization of non-const reference of
type ‘QString&’ from an rvalue of type ‘QString’
Request(manager, QString(chars[i]), doc, array, list);
I also added logging to Request
qDebug() << "queryString:" << queryString;
and also to AddDataToList
void AddDataToList(QVector<QString> &list, QJsonArray &array)
{
int count = array.count();
qDebug() << "count:" << count;
for (int n = 0; n < count; n++)
{
QString appendString = array[n].toString();
qDebug() << "index:" << n << "appendString:" << appendString;
list.append(appendString);
}
}
Then I started testing. I used shorter array of chars by changing integers to 110 -> 119 which lead to query strings n,nn, -> vu,vv
. I directed output to a file on each test round so I could analyze the results afterwards.
I got result 2984 over 10 times. During the testing session of about half an hour I got two results that differed. I compared the log files and noticed that sometimes the server returned empty response for some query strings in differing results. The count of result 2984 in parenthesis.
I got result 2816 once:
queryString: "nr"
count: 0 (18)
queryString: "ns"
count: 0 (50)
queryString: "nt"
count: 0 (50)
queryString: "nu"
count: 0 (50)
I got result 2934 once:
queryString: "or"
count: 0 (50)
I would say it's a server problem.
Addition to EDIT part of the question:
You don't get as detailed error output but anyway it's caught like this:
QJsonParseError e;
doc = QJsonDocument::fromJson(reply->readAll(), &e);
if ( e.error != QJsonParseError::NoError )
{
qWarning() << "Json parse error:" << e.errorString().toLatin1().data();
}
Here is what I got from parsing:
queryString: "uy"
Json parse error: illegal value
count: 0
See more details about QJsonParseError Class from here.
Note: There is no point of calling QCoreApplication::exec() and entering the main event loop in your current implementation.