Commit 0a423885 authored by Volker Krause's avatar Volker Krause
Browse files

Implement proper error handling and error reponse parsing for OJP

parent c6cc544e
<?xml version="1.0" encoding="UTF-8"?>
<siri:OJP xmlns:siri="http://www.siri.org.uk/siri" xmlns:ojp="http://www.vdv.de/ojp" version="1.0"><siri:OJPResponse><siri:ServiceDelivery><siri:ResponseTimestamp>2021-09-07T16:21:42Z</siri:ResponseTimestamp><siri:ProducerRef>OJPCH_Prod</siri:ProducerRef><siri:Status>true</siri:Status><ojp:OJPTripDelivery><siri:ResponseTimestamp>2021-09-07T16:21:41Z</siri:ResponseTimestamp><siri:Status>false</siri:Status><siri:ErrorCondition><siri:OtherError></siri:OtherError><siri:Description>TRIP_NOTRIPFOUND</siri:Description></siri:ErrorCondition><ojp:CalcTime>465</ojp:CalcTime></ojp:OJPTripDelivery></siri:ServiceDelivery></siri:OJPResponse></siri:OJP>
......@@ -54,6 +54,7 @@ private Q_SLOTS:
OpenJourneyPlannerParser p;
const auto res = p.parseLocationInformationResponse(readFile(inFileName));
QVERIFY(!p.hasError());
const auto jsonRes = Location::toJson(res);
const auto ref = QJsonDocument::fromJson(readFile(refFileName)).array();
......@@ -81,6 +82,7 @@ private Q_SLOTS:
OpenJourneyPlannerParser p;
const auto res = p.parseStopEventResponse(readFile(inFileName));
QVERIFY(!p.hasError());
const auto jsonRes = Stopover::toJson(res);
const auto ref = QJsonDocument::fromJson(readFile(refFileName)).array();
......@@ -108,6 +110,7 @@ private Q_SLOTS:
OpenJourneyPlannerParser p;
const auto res = p.parseTripResponse(readFile(inFileName));
QVERIFY(!p.hasError());
const auto jsonRes = Journey::toJson(res);
const auto ref = QJsonDocument::fromJson(readFile(refFileName)).array();
......@@ -117,6 +120,15 @@ private Q_SLOTS:
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
}
void testParseError()
{
OpenJourneyPlannerParser p;
const auto res = p.parseTripResponse(readFile(s(SOURCE_DIR "/data/ojp/ch-error-notripfound.xml")));
QVERIFY(res.empty());
QVERIFY(p.hasError());
QCOMPARE(p.errorMessage(), QLatin1String("TRIP_NOTRIPFOUND"));
}
};
QTEST_GUILESS_MAIN(OjpParserTest)
......
......@@ -53,10 +53,19 @@ bool OpenJourneyPlannerBackend::queryLocation(const LocationRequest &request, Lo
const auto data = netReply->readAll();
logReply(reply, netReply, data);
if (netReply->error() != QNetworkReply::NoError) {
addError(reply, Reply::NetworkError, reply->errorString());
return;
}
OpenJourneyPlannerParser p;
auto locs = p.parseLocationInformationResponse(data);
// TODO caching, error handling
addResult(reply, std::move(locs));
if (p.hasError()) {
addError(reply, Reply::NotFoundError, p.errorMessage());
} else {
// TODO caching
addResult(reply, std::move(locs));
}
});
return true;
......@@ -74,10 +83,19 @@ bool OpenJourneyPlannerBackend::queryStopover(const StopoverRequest &request, St
const auto data = netReply->readAll();
logReply(reply, netReply, data);
if (netReply->error() != QNetworkReply::NoError) {
addError(reply, Reply::NetworkError, reply->errorString());
return;
}
OpenJourneyPlannerParser p;
auto stops = p.parseStopEventResponse(data);
// TODO caching, error handling
addResult(reply, this, std::move(stops));
if (p.hasError()) {
addError(reply, Reply::NotFoundError, p.errorMessage());
} else {
// TODO caching
addResult(reply, this, std::move(stops));
}
});
return true;
......@@ -95,10 +113,19 @@ bool OpenJourneyPlannerBackend::queryJourney(const JourneyRequest &request, Jour
const auto data = netReply->readAll();
logReply(reply, netReply, data);
if (netReply->error() != QNetworkReply::NoError) {
addError(reply, Reply::NetworkError, reply->errorString());
return;
}
OpenJourneyPlannerParser p;
auto jnys = p.parseTripResponse(data);
// TODO caching, error handling
addResult(reply, this, std::move(jnys));
if (p.hasError()) {
addError(reply, Reply::NotFoundError, p.errorMessage());
} else {
// TODO caching
addResult(reply, this, std::move(jnys));
}
});
return true;
......
......@@ -19,7 +19,17 @@
using namespace KPublicTransport;
std::vector<Location> OpenJourneyPlannerParser::parseLocationInformationResponse(const QByteArray &responseData) const
bool OpenJourneyPlannerParser::hasError() const
{
return !m_errorMsg.isEmpty();
}
QString OpenJourneyPlannerParser::errorMessage() const
{
return m_errorMsg;
}
std::vector<Location> OpenJourneyPlannerParser::parseLocationInformationResponse(const QByteArray &responseData)
{
QXmlStreamReader reader(responseData);
ScopedXmlStreamReader r(reader);
......@@ -55,7 +65,7 @@ std::vector<Journey> OpenJourneyPlannerParser::parseTripResponse(const QByteArra
return {};
}
std::vector<Location> OpenJourneyPlannerParser::parseLocationInformationDelivery(ScopedXmlStreamReader &&r) const
std::vector<Location> OpenJourneyPlannerParser::parseLocationInformationDelivery(ScopedXmlStreamReader &&r)
{
std::vector<Location> l;
while (r.readNextSibling()) {
......@@ -64,6 +74,8 @@ std::vector<Location> OpenJourneyPlannerParser::parseLocationInformationDelivery
if (!loc.isEmpty()) {
l.push_back(std::move(loc));
}
} else if (r.isElement("ErrorCondition")) {
parseError(r.subReader());
}
}
return l;
......@@ -130,6 +142,8 @@ std::vector<Stopover> OpenJourneyPlannerParser::parseStopEventDelivery(ScopedXml
parseResponseContext(r.subReader());
} else if (r.isElement("StopEventResult")) {
l.push_back(parseStopEventResult(r.subReader()));
} else if (r.isElement("ErrorCondition")) {
parseError(r.subReader());
}
}
return l;
......@@ -277,6 +291,8 @@ std::vector<Journey> OpenJourneyPlannerParser::parseTripDelivery(ScopedXmlStream
parseResponseContext(r.subReader());
} else if (r.isElement("TripResult")) {
l.push_back(parseTripResult(r.subReader()));
} else if (r.isElement("ErrorCondition")) {
parseError(r.subReader());
}
}
return l;
......@@ -375,3 +391,12 @@ JourneySection OpenJourneyPlannerParser::parseTransferLeg(ScopedXmlStreamReader
}
return section;
}
void OpenJourneyPlannerParser::parseError(ScopedXmlStreamReader &&r)
{
while (r.readNextSibling()) {
if (r.isElement("Description")) {
m_errorMsg = r.readElementText();
}
}
}
......@@ -32,12 +32,15 @@ class Stopover;
class KPUBLICTRANSPORT_EXPORT OpenJourneyPlannerParser
{
public:
std::vector<Location> parseLocationInformationResponse(const QByteArray &responseData) const;
std::vector<Location> parseLocationInformationResponse(const QByteArray &responseData);
std::vector<Stopover> parseStopEventResponse(const QByteArray &responseData);
std::vector<Journey> parseTripResponse(const QByteArray &responseData);
bool hasError() const;
QString errorMessage() const;
private:
std::vector<Location> parseLocationInformationDelivery(ScopedXmlStreamReader &&r) const;
std::vector<Location> parseLocationInformationDelivery(ScopedXmlStreamReader &&r);
Location parseLocationInformationLocationOuter(ScopedXmlStreamReader &&r) const;
Location parseLocationInformationLocationInner(ScopedXmlStreamReader &&r) const;
QString parseTextElement(ScopedXmlStreamReader &&r) const;
......@@ -62,8 +65,11 @@ private:
JourneySection parseTimedLeg(ScopedXmlStreamReader &&r) const;
JourneySection parseTransferLeg(ScopedXmlStreamReader &&r) const;
void parseError(ScopedXmlStreamReader &&r);
QString m_identifierType = QStringLiteral("uic"); // TODO
QHash<QString, Location> m_contextLocations;
QString m_errorMsg;
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment