mirror of
https://github.com/meganz/MEGAcmd
synced 2025-08-22 01:47:24 +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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -211,6 +211,7 @@ private:
|
||||
|
||||
public:
|
||||
MegaCmdGlobalListener(MegaCmdLogger *logger, MegaCmdSandbox *sandboxCMD);
|
||||
|
||||
void onNodesUpdate(mega::MegaApi* api, mega::MegaNodeList *nodes);
|
||||
void onUsersUpdate(mega::MegaApi* api, mega::MegaUserList *users);
|
||||
void onAccountUpdate(mega::MegaApi *api);
|
||||
@ -281,5 +282,20 @@ protected:
|
||||
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
|
||||
#endif // LISTENERS_H
|
||||
|
@ -5341,6 +5341,13 @@ int executeServer(int argc, char* argv[],
|
||||
|
||||
api->setLanguage(localecode.c_str());
|
||||
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++)
|
||||
{
|
||||
@ -5349,9 +5356,11 @@ int executeServer(int argc, char* argv[],
|
||||
|
||||
MegaApi *apiFolder = new MegaApi("BdARkQSQ", apiFolderStrUtf8.c_str(), userAgent);
|
||||
apiFolder->setLanguage(localecode.c_str());
|
||||
apiFolders.push(apiFolder);
|
||||
apiFolder->setLogLevel(MegaApi::LOG_LEVEL_MAX);
|
||||
apiFolder->setLogJSONContent(logConfig.mJsonLogs);
|
||||
apiFolder->addGlobalListener(cmdFatalErrorListener.get());
|
||||
|
||||
apiFolders.push(apiFolder);
|
||||
semaphoreapiFolders.release();
|
||||
}
|
||||
|
||||
@ -5360,20 +5369,15 @@ int executeServer(int argc, char* argv[],
|
||||
semaphoreClients.release();
|
||||
}
|
||||
|
||||
LOG_debug << "Language set to: " << localecode;
|
||||
|
||||
if (const char* fuseLogLevelStr = getenv("MEGACMD_FUSE_LOG_LEVEL"); fuseLogLevelStr)
|
||||
{
|
||||
setFuseLogLevel(*api, fuseLogLevelStr);
|
||||
}
|
||||
|
||||
sandboxCMD = new MegaCmdSandbox();
|
||||
cmdexecuter = new MegaCmdExecuter(api, loggerCMD, sandboxCMD);
|
||||
sandboxCMD->cmdexecuter = cmdexecuter;
|
||||
|
||||
megaCmdGlobalListener = new MegaCmdGlobalListener(loggerCMD, sandboxCMD);
|
||||
megaCmdMegaListener = new MegaCmdMegaListener(api, NULL, sandboxCMD);
|
||||
api->addGlobalListener(megaCmdGlobalListener);
|
||||
api->addGlobalListener(cmdFatalErrorListener.get());
|
||||
api->addListener(megaCmdMegaListener);
|
||||
|
||||
// set up the console
|
||||
|
@ -2935,23 +2935,9 @@ void MegaCmdExecuter::fetchNodes(MegaApi *api, int clientID)
|
||||
#endif
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSession, int timeout)
|
||||
void MegaCmdExecuter::actUponLogout(MegaApi& api, MegaError* e, bool keptSession)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (srl->getError()->getErrorCode() == MegaError::API_ESID || checkNoErrors(srl->getError(), "logout"))
|
||||
if (e->getErrorCode() == MegaError::API_ESID || checkNoErrors(e, "logout"))
|
||||
{
|
||||
LOG_verbose << "actUponLogout logout ok";
|
||||
cwd = UNDEF;
|
||||
@ -2972,7 +2958,25 @@ void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSe
|
||||
clearGreetingStatusAllListener();
|
||||
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)
|
||||
|
@ -144,9 +144,10 @@ public:
|
||||
void changePassword(const char *newpassword, std::string pin2fa = "");
|
||||
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);
|
||||
int actUponLogin(mega::SynchronousRequestListener *srl, int timeout = -1);
|
||||
void actUponLogout(mega::SynchronousRequestListener *srl, bool deletedSession, int timeout = 0);
|
||||
int actUponCreateFolder(mega::SynchronousRequestListener *srl, int timeout = 0);
|
||||
int actUponLogin(mega::SynchronousRequestListener *srl, int timeout = -1);
|
||||
void actUponLogout(mega::MegaApi& api, mega::MegaError* e, bool keptSession);
|
||||
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 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user