Improve handling error messages in console mode.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2015-09-28 21:54:41 +03:00
parent 77dd8f0c77
commit 31af1687a6
10 changed files with 148 additions and 57 deletions

View File

@ -35,6 +35,7 @@
#include "../ifc/exception/vexceptionemptyparameter.h"
#include "../ifc/exception/vexceptionwrongid.h"
#include "../vmisc/logging.h"
#include "../vmisc/vsysexits.h"
#include "../qmuparser/qmuparsererror.h"
#include <QDir>
@ -89,6 +90,20 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
QCoreApplication *instance = QCoreApplication::instance();
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
switch (type)
{
case QtDebugMsg:
vStdOut() << msg << "\n";
return;
case QtWarningMsg:
case QtCriticalMsg:
case QtFatalMsg:
vStdErr() << msg << "\n";
break;
default:
break;
}
if (isGuiThread)
{
//fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will
@ -98,9 +113,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
QMessageBox messageBox;
switch (type)
{
case QtDebugMsg:
std::cout << msg.toUtf8().constData() << std::endl;
return;
case QtWarningMsg:
messageBox.setIcon(QMessageBox::Warning);
break;
@ -110,6 +122,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
case QtFatalMsg:
messageBox.setIcon(QMessageBox::Critical);
break;
case QtDebugMsg:
default:
break;
}
@ -127,10 +140,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
messageBox.exec();
}
}
else
{
std::cerr << msg.toUtf8().constData() << std::endl;
}
}
if (QtFatalMsg == type)

View File

@ -38,6 +38,7 @@
#include "../ifc/xml/vvstconverter.h"
#include "../ifc/xml/vpatternconverter.h"
#include "../vmisc/vlockguard.h"
#include "../vmisc/vsysexits.h"
#include "vlitepattern.h"
#include "../qmuparser/qmudef.h"
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
@ -162,7 +163,11 @@ void TMainWindow::LoadFile(const QString &path)
{
if (not QFileInfo(path).exists())
{
qCritical() << "File " << path << " doesn't exist";
qCritical()<<tr("File '%1' doesn't exist!").arg(path);
if (qApp->IsTestMode())
{
std::exit(V_EX_NOINPUT);
}
return;
}

View File

@ -87,13 +87,9 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
QCoreApplication *instance = QCoreApplication::instance();
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
if (isGuiThread)
{
//fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will lead to crash
const bool topWinAllowsPop = (qApp->activeModalWidget() == nullptr) || !qApp->activeModalWidget()->inherits("QFileDialog");
QString debugdate = "[" + QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
QMessageBox messageBox;
switch (type)
{
case QtDebugMsg:
@ -103,27 +99,53 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
case QtWarningMsg:
debugdate += QString(":WARNING:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
.arg(context.function).arg(context.category).arg(msg);
messageBox.setIcon(QMessageBox::Warning);
break;
case QtCriticalMsg:
debugdate += QString(":CRITICAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
.arg(context.function).arg(context.category).arg(msg);
messageBox.setIcon(QMessageBox::Critical);
break;
case QtFatalMsg:
debugdate += QString(":FATAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
.arg(context.function).arg(context.category).arg(msg);
messageBox.setIcon(QMessageBox::Critical);
break;
default:
break;
}
(*qApp->LogFile()) << debugdate << endl;
}
if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
{
vStdErr() << msg << "\n";
}
if (isGuiThread)
{
//fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will
//lead to crash
const bool topWinAllowsPop = (qApp->activeModalWidget() == nullptr) ||
!qApp->activeModalWidget()->inherits("QFileDialog");
QMessageBox messageBox;
switch (type)
{
case QtWarningMsg:
messageBox.setIcon(QMessageBox::Warning);
break;
case QtCriticalMsg:
messageBox.setIcon(QMessageBox::Critical);
break;
case QtFatalMsg:
messageBox.setIcon(QMessageBox::Critical);
break;
case QtDebugMsg:
default:
break;
}
if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
{
if (VApplication::CheckGUI())
{
if (topWinAllowsPop)
@ -135,10 +157,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
messageBox.exec();
}
}
else
{
vStdErr() << msg << "\n";
}
}
if (QtFatalMsg == type)

View File

@ -297,7 +297,7 @@ VCommandLine::~VCommandLine()
Q_NORETURN void VCommandLine::Error(const QString &text) const
{
vStdErr() << text << "\n";
const_cast<VCommandLine*>(this)->parser.showHelp(FAILED_HELP_SHOWN_STATUS);
const_cast<VCommandLine*>(this)->parser.showHelp(V_EX_USAGE);
}
//------------------------------------------------------------------------------------------------------

View File

@ -5,6 +5,7 @@
#include <QTextStream>
#include "dialogs/dialoglayoutsettings.h"
#include "../vmisc/vsysexits.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
# include "../libs/vmisc/backport/qcommandlineparser.h"
@ -12,33 +13,6 @@
# include <QCommandLineParser>
#endif
constexpr auto GENERAL_ERROR_STATUS = 255;
constexpr auto INVALID_PARAMS_STATUS = 254;
constexpr auto FAILED_TO_GEN_LAYOUT_STATUS = 253;
constexpr auto FAILED_HELP_SHOWN_STATUS = 250;
constexpr auto FAILED_GEN_BASE_STATUS = 240;
//---------------------------------------------------------------------------------------------------------------------
inline QTextStream& vStdErr()
{
static QTextStream ts( stderr );
return ts;
}
//---------------------------------------------------------------------------------------------------------------------
Q_NORETURN inline void AppAbort(const QString& text = QString(), int code = GENERAL_ERROR_STATUS)
{
//well ..std::runtime_error was leading to zombies in memory and a lot of dumping all the time ...better to do just exit
//possibly compiler do not have -fexceptions set
if (!text.isEmpty())
{
vStdErr() << text << "\n";
}
std::exit(code);
}
//---------------------------------------------------------------------------------------------------------------------
class VCommandLine;
typedef std::shared_ptr<VCommandLine> VCommandLinePtr;

View File

@ -97,13 +97,15 @@ void DialogSaveLayout::SelectFormate(const size_t formate)
{
if (formate >= availFormats.size())
{
AppAbort(tr("Tried to use out of range format number."), INVALID_PARAMS_STATUS);
qCritical() << tr("Tried to use out of range format number.");
std::exit(V_EX_USAGE);
}
int i = ui->comboBoxFormat->findData(availFormats[formate].pair.second);
if (i < 0)
{
AppAbort(tr("Selected not present format."), INVALID_PARAMS_STATUS);
qCritical() << tr("Selected not present format.");
std::exit(V_EX_USAGE);
}
ui->comboBoxFormat->setCurrentIndex(i);
}
@ -169,7 +171,7 @@ QString DialogSaveLayout::Formate() const
void DialogSaveLayout::Save()
{
for (int i=0; i < count; ++i)
{
{
const QString name = Path()+"/"+FileName()+QString::number(i+1)+Formate();
if (QFile::exists(name))
{

View File

@ -3560,8 +3560,8 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
{
if (details->count() == 0)
{
AppAbort(tr("You can't export empty scene."));
return;
qCCritical(vMainWindow, "%s", tr("You can't export empty scene.").toUtf8().constData());
std::exit(V_EX_DATAERR);
}
}
PrepareDetailsForLayout(details);

View File

@ -163,8 +163,9 @@ void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state)
default:
break;
}
//just added different return status in console mode
AppAbort(text, FAILED_GEN_BASE_STATUS + static_cast<int>(state));
qCritical() << text;
std::exit(V_EX_DATAERR);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -27,4 +27,5 @@ HEADERS += \
$$PWD/vcommonsettings.h \
$$PWD/vtapesettings.h \
$$PWD/debugbreak.h \
$$PWD/vlockguard.h
$$PWD/vlockguard.h \
$$PWD/vsysexits.h

View File

@ -0,0 +1,81 @@
/************************************************************************
**
** @file vsysexits.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 28 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2015 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VSYSEXITS_H
#define VSYSEXITS_H
#include <QTextStream>
constexpr auto V_EX_USAGE = 64; /*The command was used incorrectly, e.g., with the wrong number of arguments, a
bad flag, a bad syntax in a parameter, or whatever.*/
constexpr auto V_EX_DATAERR = 65; /*The input data was incorrect in some way. This should only be used for
user's data and not system files.*/
constexpr auto V_EX_NOINPUT = 66; /*An input file (not a system file) did not exist or was not readable.*/
constexpr auto V_EX_UNAVAILABLE = 69; /*A service is unavailable. This can occur if a support program or file does
not exist. This can also be used as a catchall message when something you
wanted to do doesn't work, but you don't know why.*/
constexpr auto V_EX_SOFTWARE = 70; /*An internal software error has been detected. This should be limited to
nonoperating operating system related errors as possible.*/
constexpr auto V_EX_OSERR = 71; /*An operating system error has been detected. This is intended to be used for
such things as ``cannot fork'', ``cannot create pipe'', or the like. It
includes things like getuid returning a user that does not exist in the passwd
file.*/
constexpr auto V_EX_OSFILE = 72; /*Some system file (e.g., /etc/passwd, /var/run/utmp, etc.) does not exist, cannot
be opened, or has some sort of error (e.g., syntax error).*/
constexpr auto V_EX_CANTCREAT = 73; /*A (user specified) output file cannot be created.*/
constexpr auto V_EX_IOERR = 74; /*An error occurred while doing I/O on some file.*/
constexpr auto V_EX_NOPERM = 77; /*You did not have sufficient permission to perform the operation. This is not
intended for file system problems, which should use EX_NOINPUT or EX_CANTCREAT,
but rather for higher level permissions.*/
constexpr auto V_EX_CONFIG = 78; /*Something was found in an unconfigured or misconfigured state.*/
//---------------------------------------------------------------------------------------------------------------------
inline QTextStream& vStdErr()
{
static QTextStream ts( stderr );
return ts;
}
//---------------------------------------------------------------------------------------------------------------------
inline QTextStream& vStdOut()
{
static QTextStream ts( stdout );
return ts;
}
#endif // VSYSEXITS_H