Commit f3164fd0 authored by Krzysztof Nowicki's avatar Krzysztof Nowicki Committed by Laurent Montel
Browse files

Parse the EWS response code and identify known errors



Parse the response codes returned by the EWS server in order to
identify some known errors and attach them to the job so that the
issuer can handle it.

For starters identify the "server busy" response in preparation for
some global handling of this error.
Signed-off-by: Krzysztof Nowicki's avatarKrzysztof Nowicki <krissn@op.pl>
parent 979a6bb4
/*
SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -9,6 +9,7 @@
EwsJob::EwsJob(QObject *parent)
: KCompositeJob(parent)
, m_ewsRespCode(EwsResponseCodeUnknown)
{
}
......
/*
SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -8,6 +8,8 @@
#include <KCompositeJob>
#include <ewstypes.h>
class EwsJob : public KCompositeJob
{
Q_OBJECT
......@@ -15,8 +17,20 @@ public:
explicit EwsJob(QObject *parent);
~EwsJob() override;
EwsResponseCode ewsResponseCode() const
{
return m_ewsRespCode;
}
protected:
bool doKill() override;
bool setErrorMsg(const QString &msg, int code = KJob::UserDefinedError);
void setEwsResponseCode(EwsResponseCode code)
{
m_ewsRespCode = code;
}
private:
EwsResponseCode m_ewsRespCode;
};
/*
SPDX-FileCopyrightText: 2015-2018 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -193,18 +193,53 @@ bool EwsRequest::readSoapBody(QXmlStreamReader &reader)
return true;
}
QPair<QStringRef, QString> EwsRequest::parseNamespacedString(const QString &str, const QXmlStreamNamespaceDeclarations &namespaces)
{
const auto tokens = str.split(QLatin1Char(':'));
switch (tokens.count()) {
case 1:
return {QStringRef(), str};
break;
case 2:
for (const auto &ns : namespaces) {
if (ns.prefix() == tokens[0]) {
return {ns.namespaceUri(), tokens[1]};
}
}
/* fall through */
default:
return {};
}
}
EwsResponseCode EwsRequest::parseEwsResponseCode(const QPair<QStringRef, QString> &code)
{
if (code.first == ewsTypeNsUri) {
return decodeEwsResponseCode(code.second);
} else {
return EwsResponseCodeUnknown;
}
}
bool EwsRequest::readSoapFault(QXmlStreamReader &reader)
{
QString faultCode;
QString faultString;
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("faultcode")) {
faultCode = reader.readElementText();
const auto rawCode = reader.readElementText();
const auto parsedCode = parseEwsResponseCode(parseNamespacedString(rawCode, reader.namespaceDeclarations()));
if (parsedCode != EwsResponseCodeUnknown) {
setEwsResponseCode(parsedCode);
}
faultCode = rawCode;
} else if (reader.name() == QLatin1String("faultstring")) {
faultString = reader.readElementText();
}
}
qCWarning(EWSCLI_LOG) << "readSoapFault" << faultCode;
setErrorMsg(faultCode + QStringLiteral(": ") + faultString);
if (EWSCLI_FAILEDREQUEST_LOG().isDebugEnabled()) {
......
/*
SPDX-FileCopyrightText: 2015-2018 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -95,6 +95,8 @@ private:
bool readHeader(QXmlStreamReader &reader);
bool readResponseAttr(const QXmlStreamAttributes &attrs, EwsResponseClass &responseClass);
QString getOAuthToken();
QPair<QStringRef, QString> parseNamespacedString(const QString &str, const QXmlStreamNamespaceDeclarations &namespaces);
EwsResponseCode parseEwsResponseCode(const QPair<QStringRef, QString> &code);
QString mBody;
EwsClient &mClient;
......
/*
SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <QMap>
#include "ewstypes.h"
const QString soapEnvNsUri = QStringLiteral("http://schemas.xmlsoap.org/soap/envelope/");
......@@ -22,3 +24,15 @@ const QVector<QString> ewsItemTypeNames = {
QStringLiteral("MeetingCancellation"),
QStringLiteral("Task"),
};
static const QMap<QString, EwsResponseCode> ewsResponseCodeMapping = {{QLatin1String("NoError"), EwsResponseCodeNoError},
{QLatin1String("ErrorServerBusy"), EwsResponseCodeErrorServerBusy}};
EwsResponseCode decodeEwsResponseCode(const QString &code)
{
if (ewsResponseCodeMapping.contains(code)) {
return ewsResponseCodeMapping[code];
} else {
return EwsResponseCodeUnknown;
}
}
/*
SPDX-FileCopyrightText: 2015-2017 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -454,6 +454,12 @@ typedef enum {
EwsUnknownEvent
} EwsEventType;
typedef enum {
EwsResponseCodeNoError,
EwsResponseCodeErrorServerBusy,
EwsResponseCodeUnknown,
} EwsResponseCode;
template<typename T> T decodeEnumString(const QString &str, const QString *table, unsigned count, bool *ok)
{
unsigned i;
......@@ -475,3 +481,4 @@ inline bool isEwsMessageItemType(EwsItemType type)
extern const QVector<QString> ewsItemTypeNames;
EwsResponseCode decodeEwsResponseCode(const QString &code);
Markdown is supported
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