mirror of
https://github.com/meganz/MEGAcmd
synced 2025-08-22 09:57:09 +00:00
Merge branch 'task/CMD-265_react_to_new_sdk_fatal_errors' into 'develop'
CMD-265. React to new EVENT_FATAL_ERROR apropiately Closes CMD-265 See merge request apps/MEGAcmd!870
This commit is contained in:
commit
511ecc03be
@ -1293,4 +1293,119 @@ bool ATransferListener::onTransferData(MegaApi *api, MegaTransfer *transfer, cha
|
|||||||
return mMultiTransferListener->onTransferData(api, transfer, buffer, size);
|
return mMultiTransferListener->onTransferData(api, transfer, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view MegaCmdFatalErrorListener::getFatalErrorStr(int64_t fatalErrorType)
|
||||||
|
{
|
||||||
|
switch (fatalErrorType)
|
||||||
|
{
|
||||||
|
case MegaEvent::REASON_ERROR_UNKNOWN: return "REASON_ERROR_UNKNOWN";
|
||||||
|
case MegaEvent::REASON_ERROR_NO_ERROR: return "REASON_ERROR_NO_ERROR";
|
||||||
|
case MegaEvent::REASON_ERROR_FAILURE_UNSERIALIZE_NODE: return "REASON_ERROR_FAILURE_UNSERIALIZE_NODE";
|
||||||
|
case MegaEvent::REASON_ERROR_DB_IO_FAILURE: return "REASON_ERROR_DB_IO_FAILURE";
|
||||||
|
case MegaEvent::REASON_ERROR_DB_FULL: return "REASON_ERROR_DB_FULL";
|
||||||
|
case MegaEvent::REASON_ERROR_DB_INDEX_OVERFLOW: return "REASON_ERROR_DB_INDEX_OVERFLOW";
|
||||||
|
case MegaEvent::REASON_ERROR_NO_JSCD: return "REASON_ERROR_NO_JSCD";
|
||||||
|
case MegaEvent::REASON_ERROR_REGENERATE_JSCD: return "REASON_ERROR_REGENERATE_JSCD";
|
||||||
|
default: assert(false);
|
||||||
|
return "<unhandled fatal error>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool localLogout>
|
||||||
|
MegaRequestListener* MegaCmdFatalErrorListener::createLogoutListener(std::string_view msg)
|
||||||
|
{
|
||||||
|
return new MegaCmdListenerFuncExecuter(
|
||||||
|
[this, msg] (mega::MegaApi *api, mega::MegaRequest *request, mega::MegaError *e)
|
||||||
|
{
|
||||||
|
broadcastMessage(std::string(msg));
|
||||||
|
mCmdSandbox.cmdexecuter->actUponLogout(*api, e, localLogout);
|
||||||
|
}, true /* autoremove */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MegaCmdFatalErrorListener::onEvent(mega::MegaApi *api, mega::MegaEvent *event)
|
||||||
|
{
|
||||||
|
assert(api); assert(event);
|
||||||
|
if (event->getType() != MegaEvent::EVENT_FATAL_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t fatalErrorType = event->getNumber();
|
||||||
|
LOG_err << "Received fatal error " << getFatalErrorStr(fatalErrorType) << " (type: " << fatalErrorType << ")";
|
||||||
|
|
||||||
|
switch (fatalErrorType)
|
||||||
|
{
|
||||||
|
case MegaEvent::REASON_ERROR_UNKNOWN:
|
||||||
|
{
|
||||||
|
broadcastMessage("An error is causing the communication with MEGA to fail. Your syncs and backups "
|
||||||
|
"are unable to update, and there may be further issues if you continue using MEGAcmd "
|
||||||
|
"without restarting. We strongly recommend immediately restarting the MEGAcmd server to "
|
||||||
|
"resolve this problem. If the issue persists, please contact support.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_NO_ERROR:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_FAILURE_UNSERIALIZE_NODE:
|
||||||
|
{
|
||||||
|
broadcastMessage("A serious issue has been detected in MEGAcmd, or in the connection between "
|
||||||
|
"this device and MEGA. Delete your local \".megaCmd\" folder and reinstall the app "
|
||||||
|
"from https://mega.io/cmd, or contact support for further assistance.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_DB_IO_FAILURE:
|
||||||
|
{
|
||||||
|
std::string_view msg = "Critical system files which are required by MEGACmd are unable to be reached. "
|
||||||
|
"Please check permissions in the \".megaCmd\" folder, or try restarting the "
|
||||||
|
"MEGAcmd server. If the issue still persists, please contact support.";
|
||||||
|
|
||||||
|
api->localLogout(createLogoutListener<true>(msg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_DB_FULL:
|
||||||
|
{
|
||||||
|
std::string_view msg = "There's not enough space in your local storage to run MEGAcmd. Please make "
|
||||||
|
"more space available before running MEGAcmd.";
|
||||||
|
|
||||||
|
api->localLogout(createLogoutListener<true>(msg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_DB_INDEX_OVERFLOW:
|
||||||
|
{
|
||||||
|
std::string_view msg = "MEGAcmd has detected a critical internal error and needs to reload. "
|
||||||
|
"You've been logged out. If you experience this issue more than once, please contact support.";
|
||||||
|
|
||||||
|
// According to the Confluence documentation on fatal errors, this should be an account reload
|
||||||
|
// We'll do a logout instead to avoid problems with api folders
|
||||||
|
api->logout(false, createLogoutListener<false>(msg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_NO_JSCD:
|
||||||
|
{
|
||||||
|
broadcastMessage("MEGAcmd has detected an error in your sync configuration data. You need to manually "
|
||||||
|
"logout of MEGAcmd, and log back in, to resolve this issue. If the problem persists "
|
||||||
|
"afterwards, please contact support.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MegaEvent::REASON_ERROR_REGENERATE_JSCD:
|
||||||
|
{
|
||||||
|
broadcastMessage("MEGAcmd has detected an error in your sync data. Please, reconfigure your syncs now. "
|
||||||
|
"If the issue persists afterwards, please contact support.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOG_err << "Unhandled fatal error type " << fatalErrorType;
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MegaCmdFatalErrorListener::MegaCmdFatalErrorListener(MegaCmdSandbox& cmdSandbox) :
|
||||||
|
mCmdSandbox(cmdSandbox)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} //end namespace
|
} //end namespace
|
||||||
|
@ -211,6 +211,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
MegaCmdGlobalListener(MegaCmdLogger *logger, MegaCmdSandbox *sandboxCMD);
|
MegaCmdGlobalListener(MegaCmdLogger *logger, MegaCmdSandbox *sandboxCMD);
|
||||||
|
|
||||||
void onNodesUpdate(mega::MegaApi* api, mega::MegaNodeList *nodes);
|
void onNodesUpdate(mega::MegaApi* api, mega::MegaNodeList *nodes);
|
||||||
void onUsersUpdate(mega::MegaApi* api, mega::MegaUserList *users);
|
void onUsersUpdate(mega::MegaApi* api, mega::MegaUserList *users);
|
||||||
void onAccountUpdate(mega::MegaApi *api);
|
void onAccountUpdate(mega::MegaApi *api);
|
||||||
@ -281,5 +282,20 @@ protected:
|
|||||||
mega::MegaTransferListener *listener;
|
mega::MegaTransferListener *listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MegaCmdFatalErrorListener : public mega::MegaGlobalListener
|
||||||
|
{
|
||||||
|
MegaCmdSandbox& mCmdSandbox;
|
||||||
|
|
||||||
|
static std::string_view getFatalErrorStr(int64_t fatalErrorType);
|
||||||
|
|
||||||
|
template<bool localLogout>
|
||||||
|
mega::MegaRequestListener* createLogoutListener(std::string_view msg);
|
||||||
|
|
||||||
|
void onEvent(mega::MegaApi *api, mega::MegaEvent *event) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MegaCmdFatalErrorListener(MegaCmdSandbox& cmdSandbox);
|
||||||
|
};
|
||||||
|
|
||||||
} //end namespace
|
} //end namespace
|
||||||
#endif // LISTENERS_H
|
#endif // LISTENERS_H
|
||||||
|
@ -5341,6 +5341,13 @@ int executeServer(int argc, char* argv[],
|
|||||||
|
|
||||||
api->setLanguage(localecode.c_str());
|
api->setLanguage(localecode.c_str());
|
||||||
api->setLogJSONContent(logConfig.mJsonLogs);
|
api->setLogJSONContent(logConfig.mJsonLogs);
|
||||||
|
LOG_debug << "Language set to: " << localecode;
|
||||||
|
|
||||||
|
sandboxCMD = new MegaCmdSandbox();
|
||||||
|
cmdexecuter = new MegaCmdExecuter(api, loggerCMD, sandboxCMD);
|
||||||
|
sandboxCMD->cmdexecuter = cmdexecuter;
|
||||||
|
|
||||||
|
auto cmdFatalErrorListener = std::make_unique<MegaCmdFatalErrorListener>(*sandboxCMD);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
@ -5349,9 +5356,11 @@ int executeServer(int argc, char* argv[],
|
|||||||
|
|
||||||
MegaApi *apiFolder = new MegaApi("BdARkQSQ", apiFolderStrUtf8.c_str(), userAgent);
|
MegaApi *apiFolder = new MegaApi("BdARkQSQ", apiFolderStrUtf8.c_str(), userAgent);
|
||||||
apiFolder->setLanguage(localecode.c_str());
|
apiFolder->setLanguage(localecode.c_str());
|
||||||
apiFolders.push(apiFolder);
|
|
||||||
apiFolder->setLogLevel(MegaApi::LOG_LEVEL_MAX);
|
apiFolder->setLogLevel(MegaApi::LOG_LEVEL_MAX);
|
||||||
apiFolder->setLogJSONContent(logConfig.mJsonLogs);
|
apiFolder->setLogJSONContent(logConfig.mJsonLogs);
|
||||||
|
apiFolder->addGlobalListener(cmdFatalErrorListener.get());
|
||||||
|
|
||||||
|
apiFolders.push(apiFolder);
|
||||||
semaphoreapiFolders.release();
|
semaphoreapiFolders.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5360,20 +5369,15 @@ int executeServer(int argc, char* argv[],
|
|||||||
semaphoreClients.release();
|
semaphoreClients.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_debug << "Language set to: " << localecode;
|
|
||||||
|
|
||||||
if (const char* fuseLogLevelStr = getenv("MEGACMD_FUSE_LOG_LEVEL"); fuseLogLevelStr)
|
if (const char* fuseLogLevelStr = getenv("MEGACMD_FUSE_LOG_LEVEL"); fuseLogLevelStr)
|
||||||
{
|
{
|
||||||
setFuseLogLevel(*api, fuseLogLevelStr);
|
setFuseLogLevel(*api, fuseLogLevelStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
sandboxCMD = new MegaCmdSandbox();
|
|
||||||
cmdexecuter = new MegaCmdExecuter(api, loggerCMD, sandboxCMD);
|
|
||||||
sandboxCMD->cmdexecuter = cmdexecuter;
|
|
||||||
|
|
||||||
megaCmdGlobalListener = new MegaCmdGlobalListener(loggerCMD, sandboxCMD);
|
megaCmdGlobalListener = new MegaCmdGlobalListener(loggerCMD, sandboxCMD);
|
||||||
megaCmdMegaListener = new MegaCmdMegaListener(api, NULL, sandboxCMD);
|
megaCmdMegaListener = new MegaCmdMegaListener(api, NULL, sandboxCMD);
|
||||||
api->addGlobalListener(megaCmdGlobalListener);
|
api->addGlobalListener(megaCmdGlobalListener);
|
||||||
|
api->addGlobalListener(cmdFatalErrorListener.get());
|
||||||
api->addListener(megaCmdMegaListener);
|
api->addListener(megaCmdMegaListener);
|
||||||
|
|
||||||
// set up the console
|
// set up the console
|
||||||
|
@ -2935,23 +2935,9 @@ void MegaCmdExecuter::fetchNodes(MegaApi *api, int clientID)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSession, int timeout)
|
void MegaCmdExecuter::actUponLogout(MegaApi& api, MegaError* e, bool keptSession)
|
||||||
{
|
{
|
||||||
if (!timeout)
|
if (e->getErrorCode() == MegaError::API_ESID || checkNoErrors(e, "logout"))
|
||||||
{
|
|
||||||
srl->wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int trywaitout = srl->trywait(timeout);
|
|
||||||
if (trywaitout)
|
|
||||||
{
|
|
||||||
LOG_err << "Logout took too long, it may have failed. No further actions performed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srl->getError()->getErrorCode() == MegaError::API_ESID || checkNoErrors(srl->getError(), "logout"))
|
|
||||||
{
|
{
|
||||||
LOG_verbose << "actUponLogout logout ok";
|
LOG_verbose << "actUponLogout logout ok";
|
||||||
cwd = UNDEF;
|
cwd = UNDEF;
|
||||||
@ -2972,7 +2958,25 @@ void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSe
|
|||||||
clearGreetingStatusAllListener();
|
clearGreetingStatusAllListener();
|
||||||
clearGreetingStatusFirstListener();
|
clearGreetingStatusFirstListener();
|
||||||
}
|
}
|
||||||
updateprompt(api);
|
updateprompt(&api);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSession, int timeout)
|
||||||
|
{
|
||||||
|
if (!timeout)
|
||||||
|
{
|
||||||
|
srl->wait();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int trywaitout = srl->trywait(timeout);
|
||||||
|
if (trywaitout)
|
||||||
|
{
|
||||||
|
LOG_err << "Logout took too long, it may have failed. No further actions performed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
actUponLogout(*api, srl->getError(), keptSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MegaCmdExecuter::actUponCreateFolder(SynchronousRequestListener *srl, int timeout)
|
int MegaCmdExecuter::actUponCreateFolder(SynchronousRequestListener *srl, int timeout)
|
||||||
|
@ -144,9 +144,10 @@ public:
|
|||||||
void changePassword(const char *newpassword, std::string pin2fa = "");
|
void changePassword(const char *newpassword, std::string pin2fa = "");
|
||||||
void actUponGetExtendedAccountDetails(std::unique_ptr<mega::MegaAccountDetails> storageDetails, std::unique_ptr<mega::MegaAccountDetails> extAccountDetails);
|
void actUponGetExtendedAccountDetails(std::unique_ptr<mega::MegaAccountDetails> storageDetails, std::unique_ptr<mega::MegaAccountDetails> extAccountDetails);
|
||||||
bool actUponFetchNodes(mega::MegaApi * api, mega::SynchronousRequestListener *srl, int timeout = -1);
|
bool actUponFetchNodes(mega::MegaApi * api, mega::SynchronousRequestListener *srl, int timeout = -1);
|
||||||
int actUponLogin(mega::SynchronousRequestListener *srl, int timeout = -1);
|
int actUponLogin(mega::SynchronousRequestListener *srl, int timeout = -1);
|
||||||
void actUponLogout(mega::SynchronousRequestListener *srl, bool deletedSession, int timeout = 0);
|
void actUponLogout(mega::MegaApi& api, mega::MegaError* e, bool keptSession);
|
||||||
int actUponCreateFolder(mega::SynchronousRequestListener *srl, int timeout = 0);
|
void actUponLogout(mega::SynchronousRequestListener *srl, bool keptSession, int timeout = 0);
|
||||||
|
int actUponCreateFolder(mega::SynchronousRequestListener *srl, int timeout = 0);
|
||||||
int deleteNode(const std::unique_ptr<mega::MegaNode>& nodeToDelete, mega::MegaApi* api, int recursive, int force = 0);
|
int deleteNode(const std::unique_ptr<mega::MegaNode>& nodeToDelete, mega::MegaApi* api, int recursive, int force = 0);
|
||||||
int deleteNodeVersions(const std::unique_ptr<mega::MegaNode>& nodeToDelete, mega::MegaApi* api, int force = 0);
|
int deleteNodeVersions(const std::unique_ptr<mega::MegaNode>& nodeToDelete, mega::MegaApi* api, int force = 0);
|
||||||
void downloadNode(std::string source, std::string localPath, mega::MegaApi* api, mega::MegaNode *node, bool background, bool ignorequotawar, int clientID, std::shared_ptr<MegaCmdMultiTransferListener> listener);
|
void downloadNode(std::string source, std::string localPath, mega::MegaApi* api, mega::MegaNode *node, bool background, bool ignorequotawar, int clientID, std::shared_ptr<MegaCmdMultiTransferListener> listener);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user