diff --git a/plugins/axivion/axivionprojectsettings.cpp b/plugins/axivion/axivionprojectsettings.cpp index 7e8dc7dfc87..3d8b11c70dc 100644 --- a/plugins/axivion/axivionprojectsettings.cpp +++ b/plugins/axivion/axivionprojectsettings.cpp @@ -112,13 +112,9 @@ void AxivionProjectSettingsWidget::fetchProjects() void AxivionProjectSettingsWidget::onDashboardInfoReceived(const DashboardInfo &info) { if (!info.error.isEmpty()) { - if (info.error.contains("credentials")) { - m_infoLabel->setText("Authentication failed. Check credentials settings."); - m_infoLabel->setType(Utils::InfoLabel::Error); - m_infoLabel->setVisible(true); - } - // send error to general message and discard results - // FIXME currently we do not get all errors - e.g. wrong curl calls + m_infoLabel->setText(info.error); + m_infoLabel->setType(Utils::InfoLabel::Error); + m_infoLabel->setVisible(true); updateEnabledStates(); return; } diff --git a/plugins/axivion/axivionquery.cpp b/plugins/axivion/axivionquery.cpp index bff033fc125..8b8cf48938f 100644 --- a/plugins/axivion/axivionquery.cpp +++ b/plugins/axivion/axivionquery.cpp @@ -39,7 +39,7 @@ AxivionQueryRunner::AxivionQueryRunner(const AxivionQuery &query, QObject *paren const AxivionServer server = settings->server; QStringList args = server.curlArguments(); - // TODO handle paginated results + args << "-i"; args << "--header" << "Authorization: AxToken " + server.token; QString url = server.dashboard; @@ -62,7 +62,7 @@ AxivionQueryRunner::AxivionQueryRunner(const AxivionQuery &query, QObject *paren start(); return; } - // output error to general message + emit resultRetrieved(m_process.readAllStandardError()); } else { emit resultRetrieved(m_process.readAllStandardOutput()); } diff --git a/plugins/axivion/axivionresultparser.cpp b/plugins/axivion/axivionresultparser.cpp index 59f90854d37..5ef89a1cce1 100644 --- a/plugins/axivion/axivionresultparser.cpp +++ b/plugins/axivion/axivionresultparser.cpp @@ -6,9 +6,69 @@ #include #include #include +#include + +#include namespace Axivion::Internal { +static std::pair splitHeaderAndBody(const QByteArray &input) +{ + QByteArray header; + QByteArray json; + int emptyLine = input.indexOf("\r\n\r\n"); // we always get \r\n as line separator + if (emptyLine != -1) { + header = input.left(emptyLine); + json = input.mid(emptyLine + 4); + } else { + json = input; + } + return {header, json}; +} + +static int httpStatus(const QByteArray &header) +{ + int firstHeaderEnd = header.indexOf("\r\n"); + if (firstHeaderEnd == -1) + return 600; // unexpected header + const QString firstLine = QString::fromUtf8(header.first(firstHeaderEnd)); + static const QRegularExpression regex(R"(^HTTP/\d\.\d (\d{3}) .*$)"); + const QRegularExpressionMatch match = regex.match(firstLine); + return match.hasMatch() ? match.captured(1).toInt() : 601; +} + +static std::pair prehandleHeaderAndBody(const QByteArray &header, + const QByteArray &body) +{ + BaseResult result; + if (header.isEmpty()) { + result.error = QString::fromUtf8(body); // we likely had a curl problem + return {result, {}}; + } + int status = httpStatus(header); + if ((status > 399) || (status > 299 && body.isEmpty())) { // FIXME handle some explicitly? + const QString statusStr = QString::number(status); + if (body.isEmpty() || body.startsWith('<')) // likely an html response or redirect + result.error = QLatin1String("(%1)").arg(statusStr); + else + result.error = QLatin1String("%1 (%2)").arg(QString::fromUtf8(body)).arg(statusStr); + return {result, {}}; + } + + QJsonParseError error; + const QJsonDocument doc = QJsonDocument::fromJson(body, &error); + if (error.error != QJsonParseError::NoError) { + result.error = error.errorString(); + return {result, doc}; + } + + if (!doc.isObject()) { + result.error = "Not an object."; + return {result, {}}; + } + + return {result, doc}; +} namespace ResultParser { @@ -16,18 +76,10 @@ DashboardInfo parseDashboardInfo(const QByteArray &input) { DashboardInfo result; - QJsonParseError error; - const QJsonDocument doc = QJsonDocument::fromJson(input, &error); - if (error.error != QJsonParseError::NoError) { - if (input.startsWith("Authentication failed:")) - result.error = QString::fromUtf8(input); - else - result.error = error.errorString(); - return result; - } - - if (!doc.isObject()) { - result.error = "Not an object."; + auto [header, body] = splitHeaderAndBody(input); + auto [error, doc] = prehandleHeaderAndBody(header, body); + if (!error.error.isEmpty()) { + result.error = error.error; return result; } const QJsonObject object = doc.object();