Improve handling error messages in console mode.
--HG-- branch : develop
This commit is contained in:
parent
77dd8f0c77
commit
31af1687a6
|
@ -35,6 +35,7 @@
|
||||||
#include "../ifc/exception/vexceptionemptyparameter.h"
|
#include "../ifc/exception/vexceptionemptyparameter.h"
|
||||||
#include "../ifc/exception/vexceptionwrongid.h"
|
#include "../ifc/exception/vexceptionwrongid.h"
|
||||||
#include "../vmisc/logging.h"
|
#include "../vmisc/logging.h"
|
||||||
|
#include "../vmisc/vsysexits.h"
|
||||||
#include "../qmuparser/qmuparsererror.h"
|
#include "../qmuparser/qmuparsererror.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -89,6 +90,20 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
QCoreApplication *instance = QCoreApplication::instance();
|
QCoreApplication *instance = QCoreApplication::instance();
|
||||||
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
|
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)
|
if (isGuiThread)
|
||||||
{
|
{
|
||||||
//fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will
|
//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;
|
QMessageBox messageBox;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case QtDebugMsg:
|
|
||||||
std::cout << msg.toUtf8().constData() << std::endl;
|
|
||||||
return;
|
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
messageBox.setIcon(QMessageBox::Warning);
|
messageBox.setIcon(QMessageBox::Warning);
|
||||||
break;
|
break;
|
||||||
|
@ -110,6 +122,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
messageBox.setIcon(QMessageBox::Critical);
|
messageBox.setIcon(QMessageBox::Critical);
|
||||||
break;
|
break;
|
||||||
|
case QtDebugMsg:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -127,10 +140,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
messageBox.exec();
|
messageBox.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << msg.toUtf8().constData() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QtFatalMsg == type)
|
if (QtFatalMsg == type)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "../ifc/xml/vvstconverter.h"
|
#include "../ifc/xml/vvstconverter.h"
|
||||||
#include "../ifc/xml/vpatternconverter.h"
|
#include "../ifc/xml/vpatternconverter.h"
|
||||||
#include "../vmisc/vlockguard.h"
|
#include "../vmisc/vlockguard.h"
|
||||||
|
#include "../vmisc/vsysexits.h"
|
||||||
#include "vlitepattern.h"
|
#include "vlitepattern.h"
|
||||||
#include "../qmuparser/qmudef.h"
|
#include "../qmuparser/qmudef.h"
|
||||||
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
||||||
|
@ -162,7 +163,11 @@ void TMainWindow::LoadFile(const QString &path)
|
||||||
{
|
{
|
||||||
if (not QFileInfo(path).exists())
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,13 +87,9 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
QCoreApplication *instance = QCoreApplication::instance();
|
QCoreApplication *instance = QCoreApplication::instance();
|
||||||
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
|
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");
|
QString debugdate = "[" + QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
|
||||||
QMessageBox messageBox;
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case QtDebugMsg:
|
case QtDebugMsg:
|
||||||
|
@ -103,27 +99,53 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
debugdate += QString(":WARNING:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
debugdate += QString(":WARNING:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
||||||
.arg(context.function).arg(context.category).arg(msg);
|
.arg(context.function).arg(context.category).arg(msg);
|
||||||
messageBox.setIcon(QMessageBox::Warning);
|
|
||||||
break;
|
break;
|
||||||
case QtCriticalMsg:
|
case QtCriticalMsg:
|
||||||
debugdate += QString(":CRITICAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
debugdate += QString(":CRITICAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
||||||
.arg(context.function).arg(context.category).arg(msg);
|
.arg(context.function).arg(context.category).arg(msg);
|
||||||
messageBox.setIcon(QMessageBox::Critical);
|
|
||||||
break;
|
break;
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
debugdate += QString(":FATAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
debugdate += QString(":FATAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line)
|
||||||
.arg(context.function).arg(context.category).arg(msg);
|
.arg(context.function).arg(context.category).arg(msg);
|
||||||
messageBox.setIcon(QMessageBox::Critical);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*qApp->LogFile()) << debugdate << endl;
|
(*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 (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (VApplication::CheckGUI())
|
if (VApplication::CheckGUI())
|
||||||
{
|
{
|
||||||
if (topWinAllowsPop)
|
if (topWinAllowsPop)
|
||||||
|
@ -135,10 +157,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
|
||||||
messageBox.exec();
|
messageBox.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
vStdErr() << msg << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QtFatalMsg == type)
|
if (QtFatalMsg == type)
|
||||||
|
|
|
@ -297,7 +297,7 @@ VCommandLine::~VCommandLine()
|
||||||
Q_NORETURN void VCommandLine::Error(const QString &text) const
|
Q_NORETURN void VCommandLine::Error(const QString &text) const
|
||||||
{
|
{
|
||||||
vStdErr() << text << "\n";
|
vStdErr() << text << "\n";
|
||||||
const_cast<VCommandLine*>(this)->parser.showHelp(FAILED_HELP_SHOWN_STATUS);
|
const_cast<VCommandLine*>(this)->parser.showHelp(V_EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "dialogs/dialoglayoutsettings.h"
|
#include "dialogs/dialoglayoutsettings.h"
|
||||||
|
#include "../vmisc/vsysexits.h"
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
|
||||||
# include "../libs/vmisc/backport/qcommandlineparser.h"
|
# include "../libs/vmisc/backport/qcommandlineparser.h"
|
||||||
|
@ -12,33 +13,6 @@
|
||||||
# include <QCommandLineParser>
|
# include <QCommandLineParser>
|
||||||
#endif
|
#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;
|
class VCommandLine;
|
||||||
typedef std::shared_ptr<VCommandLine> VCommandLinePtr;
|
typedef std::shared_ptr<VCommandLine> VCommandLinePtr;
|
||||||
|
|
||||||
|
|
|
@ -97,13 +97,15 @@ void DialogSaveLayout::SelectFormate(const size_t formate)
|
||||||
{
|
{
|
||||||
if (formate >= availFormats.size())
|
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);
|
int i = ui->comboBoxFormat->findData(availFormats[formate].pair.second);
|
||||||
if (i < 0)
|
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);
|
ui->comboBoxFormat->setCurrentIndex(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3560,8 +3560,8 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
|
||||||
{
|
{
|
||||||
if (details->count() == 0)
|
if (details->count() == 0)
|
||||||
{
|
{
|
||||||
AppAbort(tr("You can't export empty scene."));
|
qCCritical(vMainWindow, "%s", tr("You can't export empty scene.").toUtf8().constData());
|
||||||
return;
|
std::exit(V_EX_DATAERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrepareDetailsForLayout(details);
|
PrepareDetailsForLayout(details);
|
||||||
|
|
|
@ -163,8 +163,9 @@ void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state)
|
||||||
default:
|
default:
|
||||||
break;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -27,4 +27,5 @@ HEADERS += \
|
||||||
$$PWD/vcommonsettings.h \
|
$$PWD/vcommonsettings.h \
|
||||||
$$PWD/vtapesettings.h \
|
$$PWD/vtapesettings.h \
|
||||||
$$PWD/debugbreak.h \
|
$$PWD/debugbreak.h \
|
||||||
$$PWD/vlockguard.h
|
$$PWD/vlockguard.h \
|
||||||
|
$$PWD/vsysexits.h
|
||||||
|
|
81
src/libs/vmisc/vsysexits.h
Normal file
81
src/libs/vmisc/vsysexits.h
Normal 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
|
Loading…
Reference in New Issue
Block a user