forked from qt-creator/qt-creator
Tweak error handling a bit
Always get http headers of the response to be able to handle issues more explicitly. These headers also contain additional information we will need later on. Change-Id: I062e97726a473c16b29cd84be0aa37260bac4ed8 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -6,9 +6,69 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace Axivion::Internal {
|
||||
|
||||
static std::pair<QByteArray, QByteArray> 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<BaseResult, QJsonDocument> 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();
|
||||
|
||||
Reference in New Issue
Block a user