The program has unexpectedly finished. try catch throw in Qt - qt

I have a problem in my qt project, when an exception is thrown my windows crash and close, why? Where is the problem? I do not understand.
class MyException:public std::exception{
private:
QMessageBox* mex;
public:
MyException(QString);
};
class err_parser_binary:public MyException{
public:
err_parser_binary(QString);
};
MyException::MyException(QString d):mex(new QMessageBox()){
mex->setText("Error");
mex->setDetailedText(d);
mex->button(QMessageBox::Ok);
mex->show();
}
err_parser_binary::err_parser_binary(QString detail): MyException(detail){
}
QString binary_controller::calcolaop1op2(QString x, QString y, QString op) try{
...............
Binary* pb=new Binary(op2);
..................
}
catch (err_parser_binary) {}
Binary::Binary(std::string str){
......
throw err_parser_binary("only 1 o 0");
......
}

From what I've read, Qt is not really exception safe. Take a look at this page. At the top, it says:
Preliminary warning: Exception safety is not feature complete! Common
cases should work, but classes might still leak or even crash.
Qt itself will not throw exceptions. Instead, error codes are used. In
addition, some classes have user visible error messages, for example
QIODevice::errorString() or QSqlQuery::lastError(). This has
historical and practical reasons - turning on exceptions can increase
the library size by over 20%.
You should just use error codes and/or error messages instead.

Related

How to deal with RedisMessageListenerContainer death

I've encountered a case where the redis pubsub RedisMessageListenerContainer in my spring boot application died with
ERROR .RedisMessageListenerContainer: SubscriptionTask aborted with exception:
org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is com.lambdaworks.redis.RedisCommandTimeoutException: Command timed out
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:66)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:330)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.subscribe(LettuceConnection.java:3179)
at org.springframework.data.redis.listener.RedisMessageListenerContainer$SubscriptionTask.eventuallyPerformSubscription(RedisMessageListenerContainer.java:790)
at org.springframework.data.redis.listener.RedisMessageListenerContainer$SubscriptionTask.run(RedisMessageListenerContainer.java:746)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.lambdaworks.redis.RedisCommandTimeoutException: Command timed out
at com.lambdaworks.redis.LettuceFutures.await(LettuceFutures.java:113)
at com.lambdaworks.redis.LettuceFutures.awaitOrCancel(LettuceFutures.java:92)
at com.lambdaworks.redis.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:63)
at com.lambdaworks.redis.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80)
at com.sun.proxy.$Proxy156.subscribe(Unknown Source)
at org.springframework.data.redis.connection.lettuce.LettuceSubscription.doSubscribe(LettuceSubscription.java:63)
at org.springframework.data.redis.connection.util.AbstractSubscription.subscribe(AbstractSubscription.java:142)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.subscribe(LettuceConnection.java:3176)
... 3 common frames omitted
..
I think that shouldn't be an unrecoverable error in the first place because it's a temporary connection issue (and a TransientDataAccessException) but the application apparently needs to deal with exceptions in those case.
Currently this leaves the application in a state that is not acceptable. It merely logs the error but I would either need to kill the application so it gets replaced or better try to restart that container and ideally report via /health that the application is impacted as long as it's not all good.
Is there anything I'm overlooking that is less awkward than either trying to start() the container every x seconds or subclass it and overwrite handleSubscriptionException() and try to act from there? The latter needs much deeper integration with internals than I'd like to have in my code but it's what I so far went with:
RedisMessageListenerContainer container = new RedisMessageListenerContainer() {
#Override
protected void handleSubscriptionException(Throwable ex) {
super.handleSubscriptionException(ex); // don't know what actually happened in here and no way to find out :/
if (ex instanceof RedisConnectionFailureException) {
// handled by super hopefully, don't care
} else if (ex instanceof InterruptedException){
// can ignore those I guess
} else if (ex instanceof TransientDataAccessException || ex instanceof RecoverableDataAccessException) {
// try to restart in those cases?
if (isRunning()) {
logger.error("Connection failure occurred. Restarting subscription task manually due to " + ex, ex);
sleepBeforeRecoveryAttempt();
start(); // best we can do
}
} else {
// otherwise shutdown and hope for the best next time
if (isRunning()) {
logger.warn("Shutting down application due to unknown exception " + ex, ex);
context.close();
}
}
}
};

I can't quit properly my apps if I use mysql connection

If I do not use connection I can properly exit.
In Pdv.h file
namespace Pdv {
...
extern QSqlDatabase db;
...
}
In LoginDialog.cpp file
QSqlDatabase Pdv::db;
...
Pdv::db= QSqlDatabase::addDatabase("QMYSQL3");
Pdv::db.setHostName(Pdv::DB_URL);
Pdv::db.setUserName(Pdv::DB_USER);
Pdv::db.setPassword(Pdv::DB_PASS);
Pdv::db.setDatabaseName(Pdv::DB_DB);
if(!Pdv::db.open()) {
...
// Checking user login/password and retrieve many variables
...
In mainwindow.cpp file
...
void MainWindow::closeEvent(QCloseEvent *event) {
...
if(Pdv::db.isOpen()) {
qDebug() << "Opened 1";
Pdv::db.close();
qDebug() << Pdv::db.lastError();
if(Pdv::db.isOpen())
qDebug() << "Opened 2";
}
Pdv::app->quit(); // or QApplication::quit();
}
I got this error in QTCreator console
Opened 1
QSqlError("", "", "")
Le programme s'est terminé subitement.
/home/cosmic/src/build-Pdv-Desktop-Debug/Pdv crashed.
A idea?
To make proper exit with usage of QSqlDatabase, you need preferably:
remove all instances of QSqlDatabase objects (because as you copy them, they will keep connection open).
As second condition, you need to use QSqlDatabe::removeDatabase() call. (also this call will make qDebug message if database is still in use occasionally - some QSqlDatabase object is left somewhere - it will help to identify a problem).
If you close and delete your MainWindow, and your program then crashes, then other parts of the program must be trying to use the MainWindow pointer even though it is destroyed.
I think the problem is the line of code Pdv::app->quit(); Try with QApplication::quit(); instead or review the code in Pdv::app->quit();.

Error while connecting lambda function to QProcess::error

In following code I want to connect lambda function to QProcess::error signal:
void Updater::start() {
QProcess process;
QObject::connect(&process, &QProcess::error, [=] (QProcess::ProcessError error) {
qWarning() << "error " << error;
});
process.start("MyProgram");
process.waitForFinished();
}
But I get strange error:
error: no matching function for call to 'Updater::connect(QProcess*
[unresolved overloaded function type],
Updater::start()::)' });
What I do wrong here? The code executes inside method of class derived from QObject. The project configured to work with c++11.
I use Qt 5.3.1 on Linux x32 with gcc 4.9.2
Problem is that the QProcess has another error() method, so compiler just doesn't know which method use. If you want to deal with overloaded methods, you should use next:
QProcess process;
connect(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>
(&QProcess::error), [=](QProcess::ProcessError pError) {
qWarning() << "error " << pError;
});
process.start("MyProgram");
process.waitForFinished();
Yes, it looks ugly, but there is no another way (only old syntax?).
This special line tells compiler that you want to use void QProcess::error(QProcess::ProcessError error), so now there is no any ambiguity
More information you can find here.
For those who are using Qt 5.6 or later, the QProcess::error signal is deprecated. You can use the QProcess::errorOccurred signal instead to avoid the naming ambiguity and complicated casting.
QProcess process;
connect(&process, &QProcess::errorOccurred, [=](QProcess::ProcessError error) {
qWarning() << error;
});
process.start("MyProgram");
process.waitForFinished();

Photon Networking Instantiate Error (Unity3d)

Ok, so I'm making an online FPS in Unity and I was scripting that Photon Networking Script to connect and spawn the player and I keep getting these two errors:
Assets/Resources/GameManager.cs(64,23): error CS1502: The best overloaded method match for `PhotonNetwork.Instantiate(string, UnityEngine.Vector3, UnityEngine.Quaternion, int)' has some invalid arguments
Assets/Resources/GameManager.cs(64,23): error CS1503: Argument `#1' cannot convert `UnityEngine.Transform' expression to type `string'
Here is where the error is in my code:
// When Connected [Photon Callback]
void OnJoinedRoom()
{
PhotonNetwork.Instantiate(playerPrefab, transform.position, Quaternion.identity, 0);
}
//In Game: Disconnect from room.
void InGameGUI()
{
if (GUILayout.Button("Leave Game"))
PhotonNetwork.LeaveRoom();
}
}
And I did reference the Transform at the top:
public Transform playerPrefab;
Any ideas on what I did wrong and how I could fix it. Please help!
PhotonNetwork.Instantiate requires a string, not a Transform object as it's first parameter. (I do believe this was changed from a Transform object a while ago). Simply name the prefab that you want to instantiate (which must be in the Resources folder).

Error codes for CryptographicExceptions?

I'm trying to map different CryptographicExceptions to custom exceptions and messages. For example, "Object already exists" ==> "Not enough permissions to access an existing RSA key container". However, when I examine CryptographicException class, I don't find any error code collection like other exception types have. I'm running on 3.5, so HResult is not available either. Finally, I cannot rely on the message, since it can be localized. Any other ideas?
public Exception GetMappedCryptographicException(CryptographicException e)
{
uint hresult = (uint)Marshal.GetHRForException(e);
switch (hresult)
{
case 0x8009000F; // OBJECT_ALREADY_EXISTS
return new Exception(e, "Not enough permissions to access RSA key container.");
default:
return new Exception(e, "Unexpected cryptographic exception occurred.");
}
}

Resources