From e1a3aebafca9a9447a393100db4fc45943551630 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 31 Oct 2017 14:04:03 +0100 Subject: Ensure we get an appropriate exit code when a resource crashes. --- common/domain/applicationdomaintype.h | 3 ++- common/resourceaccess.cpp | 4 ++++ common/resourcecontrol.cpp | 7 +++++-- sinksh/state.cpp | 2 +- sinksh/syntax_modules/sink_sync.cpp | 4 +++- sinksh/syntaxtree.cpp | 10 +++++----- sinksh/syntaxtree.h | 2 +- 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index de2b5c9..dc4cbe1 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h @@ -102,7 +102,8 @@ enum SINK_EXPORT ErrorCode { ConfigurationError, TransmissionError, ConnectionLostError, - MissingCredentialsError + MissingCredentialsError, + ResourceCrashedError }; enum SINK_EXPORT SuccessCode { diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp index a3478e6..8b70684 100644 --- a/common/resourceaccess.cpp +++ b/common/resourceaccess.cpp @@ -526,6 +526,10 @@ void ResourceAccess::connectionError(QLocalSocket::LocalSocketError error) Sink::Notification n; n.type = Sink::Notification::Status; emit notification(n); + Sink::Notification crashNotification; + crashNotification.type = Sink::Notification::Error; + crashNotification.code = Sink::ApplicationDomain::ResourceCrashedError; + emit notification(crashNotification); d->abortPendingOperations(); } else if (error == QLocalSocket::PeerClosedError) { SinkLog() << "The resource closed the connection."; diff --git a/common/resourcecontrol.cpp b/common/resourcecontrol.cpp index b6a4c0b..a69b7fa 100644 --- a/common/resourcecontrol.cpp +++ b/common/resourcecontrol.cpp @@ -101,10 +101,13 @@ KAsync::Job ResourceControl::flush(Flush::FlushType type, const QByteArray SinkTrace() << "Waiting for flush completion notification " << id; notifier->registerHandler([&future, id](const Notification ¬ification) { SinkTrace() << "Received notification: " << notification.type << notification.id; - if (notification.id == id) { + if (notification.type == Notification::Error && notification.code == ApplicationDomain::ResourceCrashedError) { + SinkWarning() << "Error during flush"; + future.setError(-1, "Error during flush: " + notification.message); + } else if (notification.id == id) { SinkTrace() << "FlushComplete"; if (notification.code) { - SinkWarning() << "Flush return an error"; + SinkWarning() << "Flush returned an error"; future.setError(-1, "Flush returned an error: " + notification.message); } else { future.setFinished(); diff --git a/sinksh/state.cpp b/sinksh/state.cpp index 7e04d28..b7e8e5a 100644 --- a/sinksh/state.cpp +++ b/sinksh/state.cpp @@ -139,7 +139,7 @@ int State::commandStarted() const void State::commandFinished(int returnCode) const { - SinkTrace() << "Command finished"; + SinkTrace() << "Command finished. Exit code: " << returnCode; if (!s_hasEventLoop) { QCoreApplication::exit(returnCode); } else { diff --git a/sinksh/syntax_modules/sink_sync.cpp b/sinksh/syntax_modules/sink_sync.cpp index 2800af1..8b48785 100644 --- a/sinksh/syntax_modules/sink_sync.cpp +++ b/sinksh/syntax_modules/sink_sync.cpp @@ -67,12 +67,14 @@ bool sync(const QStringList &args, State &state) Sink::Store::synchronize(query) .then(Sink::ResourceControl::flushMessageQueue(query.getResourceFilter().ids)) .then([state](const KAsync::Error &error) { + int exitCode = 0; if (error) { state.printLine("Synchronization failed!"); + exitCode = 1; } else { state.printLine("Synchronization complete!"); } - state.commandFinished(); + state.commandFinished(exitCode); }).exec(); return true; diff --git a/sinksh/syntaxtree.cpp b/sinksh/syntaxtree.cpp index ee9d6f8..65eb769 100644 --- a/sinksh/syntaxtree.cpp +++ b/sinksh/syntaxtree.cpp @@ -57,16 +57,16 @@ Syntax::List SyntaxTree::syntax() const return m_syntax; } -bool SyntaxTree::run(const QStringList &commands) +int SyntaxTree::run(const QStringList &commands) { - bool success = false; + int returnCode = 0; m_timeElapsed.start(); Command command = match(commands); if (command.first) { if (command.first->lambda) { - success = command.first->lambda(command.second, m_state); + bool success = command.first->lambda(command.second, m_state); if (success && command.first->interactivity == Syntax::EventDriven) { - success = m_state.commandStarted(); + returnCode = m_state.commandStarted(); } } else if (command.first->children.isEmpty()) { m_state.printError(QObject::tr("Broken command... sorry :("), "st_broken"); @@ -85,7 +85,7 @@ bool SyntaxTree::run(const QStringList &commands) if (m_state.commandTiming()) { m_state.printLine(QObject::tr("Time elapsed: %1").arg(m_timeElapsed.elapsed())); } - return false; + return returnCode; } SyntaxTree::Command SyntaxTree::match(const QStringList &commandLine) const diff --git a/sinksh/syntaxtree.h b/sinksh/syntaxtree.h index 6624388..8fbbd01 100644 --- a/sinksh/syntaxtree.h +++ b/sinksh/syntaxtree.h @@ -63,7 +63,7 @@ public: Command match(const QStringList &commands) const; Syntax::List nearestSyntax(const QStringList &words, const QString &fragment) const; State &state(); - bool run(const QStringList &commands); + int run(const QStringList &commands); static QStringList tokenize(const QString &text); -- cgit v1.2.3