From f77396a09ead579000bda312b1220e3ff2ab8653 Mon Sep 17 00:00:00 2001 From: Anthony Bilinski Date: Wed, 11 Sep 2019 14:21:24 -0700 Subject: [PATCH] refactor(core): parse and log all toxcore errors Use a macro to embed line number of call sight, instead of just using line number of log site, since logger functions can be called from different toxcore API usages. --- src/core/core.cpp | 618 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 431 insertions(+), 187 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index dc9363194..6a0beb730 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -47,148 +47,427 @@ const QString Core::TOX_EXT = ".tox"; #define ASSERT_CORE_THREAD assert(QThread::currentThread() == coreThread.get()) namespace { -bool LogConferenceTitleError(TOX_ERR_CONFERENCE_TITLE error) +/** + * @brief Parse and log toxcore error enums. + * @param error Error to handle. + * @return True if no error, false otherwise. + */ + +#define PARSE_ERR(ERROR_TYPE, err) parse##ERROR_TYPE(err, __LINE__) + +bool parseToxErrConferenceTitle(Tox_Err_Conference_Title error, int line) { switch (error) { case TOX_ERR_CONFERENCE_TITLE_OK: - break; + return true; + case TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND: - qWarning() << "Conference title not found"; - break; + qCritical() << line << ": Conference title not found"; + return false; + case TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH: - qWarning() << "Invalid conference title length"; - break; + qCritical() << line << ": Invalid conference title length"; + return false; + case TOX_ERR_CONFERENCE_TITLE_FAIL_SEND: - qWarning() << "Failed to send title packet"; + qCritical() << line << ": Failed to send title packet"; + return false; + + default: + qCritical() << line << ": Unknown Tox_Err_Conference_Title error code:" << error; + return false; } - return error; } -bool parseFriendSendMessageError(Tox_Err_Friend_Send_Message error) +bool parseToxErrFriendSendMessage(Tox_Err_Friend_Send_Message error, int line) { switch (error) { case TOX_ERR_FRIEND_SEND_MESSAGE_OK: return true; + case TOX_ERR_FRIEND_SEND_MESSAGE_NULL: - qCritical() << "Send friend message passed an unexpected null argument"; + qCritical() << line << "Send friend message passed an unexpected null argument"; return false; + case TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND: - qCritical() << "Send friend message could not find friend"; + qCritical() << line << "Send friend message could not find friend"; return false; + case TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED: - qCritical() << "Send friend message: friend is offline"; + qCritical() << line << "Send friend message: friend is offline"; return false; + case TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ: - qCritical() << "Failed to allocate more message queue"; + qCritical() << line << "Failed to allocate more message queue"; return false; + case TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG: - qCritical() << "Attemped to send message that's too long"; + qCritical() << line << "Attemped to send message that's too long"; return false; + case TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY: - qCritical() << "Attempted to send an empty message"; + qCritical() << line << "Attempted to send an empty message"; return false; + default: - qCritical() << "Unknown friend send message error:" << static_cast(error); + qCritical() << line << "Unknown friend send message error:" << static_cast(error); return false; } } -bool parseConferenceSendMessageError(Tox_Err_Conference_Send_Message error) +bool parseToxErrConferenceSendMessage(Tox_Err_Conference_Send_Message error, int line) { switch (error) { case TOX_ERR_CONFERENCE_SEND_MESSAGE_OK: return true; case TOX_ERR_CONFERENCE_SEND_MESSAGE_CONFERENCE_NOT_FOUND: - qCritical() << "Conference not found"; + qCritical() << line << "Conference not found"; return false; case TOX_ERR_CONFERENCE_SEND_MESSAGE_FAIL_SEND: - qCritical() << "Conference message failed to send"; + qCritical() << line << "Conference message failed to send"; return false; case TOX_ERR_CONFERENCE_SEND_MESSAGE_NO_CONNECTION: - qCritical() << "No connection"; + qCritical() << line << "No connection"; return false; case TOX_ERR_CONFERENCE_SEND_MESSAGE_TOO_LONG: - qCritical() << "Message too long"; + qCritical() << line << "Message too long"; return false; + default: - qCritical() << "Unknown Tox_Err_Conference_Send_Message error:" << static_cast(error); + qCritical() << line << "Unknown Tox_Err_Conference_Send_Message error:" << static_cast(error); return false; } } -/** - * @brief Print in console text of error. - * @param error Error to handle. - * @return True if no error, false otherwise. - */ -bool parsePeerQueryError(Tox_Err_Conference_Peer_Query error) +bool parseToxErrConferencePeerQuery(Tox_Err_Conference_Peer_Query error, int line) { switch (error) { case TOX_ERR_CONFERENCE_PEER_QUERY_OK: return true; case TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND: - qCritical() << "Conference not found"; + qCritical() << line << "Conference not found"; return false; case TOX_ERR_CONFERENCE_PEER_QUERY_NO_CONNECTION: - qCritical() << "No connection"; + qCritical() << line << "No connection"; return false; case TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND: - qCritical() << "Peer not found"; + qCritical() << line << "Peer not found"; return false; default: - qCritical() << "Unknown error code:" << error; + qCritical() << line << "Unknown Tox_Err_Conference_Peer_Query error code:" << error; return false; } } -/** - * @brief Print in console text of error. - * @param error Error to handle. - * @return True if no error, false otherwise. - */ -bool parseConferenceJoinError(Tox_Err_Conference_Join error) +bool parseToxErrConferenceJoin(Tox_Err_Conference_Join error, int line) { switch (error) { case TOX_ERR_CONFERENCE_JOIN_OK: return true; case TOX_ERR_CONFERENCE_JOIN_DUPLICATE: - qCritical() << "Conference duplicate"; + qCritical() << line << "Conference duplicate"; return false; case TOX_ERR_CONFERENCE_JOIN_FAIL_SEND: - qCritical() << "Conference join failed to send"; + qCritical() << line << "Conference join failed to send"; return false; case TOX_ERR_CONFERENCE_JOIN_FRIEND_NOT_FOUND: - qCritical() << "Friend not found"; + qCritical() << line << "Friend not found"; return false; case TOX_ERR_CONFERENCE_JOIN_INIT_FAIL: - qCritical() << "Init fail"; + qCritical() << line << "Init fail"; return false; case TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH: - qCritical() << "Invalid length"; + qCritical() << line << "Invalid length"; return false; case TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE: - qCritical() << "Wrong conference type"; + qCritical() << line << "Wrong conference type"; return false; default: - qCritical() << "Unknown error code:" << error; + qCritical() << line << "Unknown Tox_Err_Conference_Join error code:" << error; return false; } } + +bool parseToxErrConferenceGetType(Tox_Err_Conference_Get_Type error, int line) +{ + switch (error) { + case TOX_ERR_CONFERENCE_GET_TYPE_OK: + return true; + + case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND: + qCritical() << line << "Conference not found"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Conference_Get_Type error code:" << error; + return false; + } +} + +bool parseToxErrConferenceInvite(Tox_Err_Conference_Invite error, int line) +{ + switch (error) { + case TOX_ERR_CONFERENCE_INVITE_OK: + return true; + + case TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND: + qCritical() << line << "Conference not found"; + return false; + + case TOX_ERR_CONFERENCE_INVITE_FAIL_SEND: + qCritical() << line << "Conference invite failed to send"; + return false; + + case TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION: + qCritical() << line << "Cannot invite to conference that we're not connected to"; + return false; + + default: + qWarning() << "Unknown Tox_Err_Conference_Invite error code:" << error; + return false; + } +} + +bool parseToxErrConferenceNew(Tox_Err_Conference_New error, int line) +{ + switch (error) { + case TOX_ERR_CONFERENCE_NEW_OK: + return true; + + case TOX_ERR_CONFERENCE_NEW_INIT: + qCritical() << line << "The conference instance failed to initialize"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Conference_New error code:" << error; + return false; + } +} + +bool parseToxErrFriendByPublicKey(Tox_Err_Friend_By_Public_Key error, int line) +{ + switch (error) { + case TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK: + return true; + + case TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL: + qCritical() << line << "null argument when not expected"; + return false; + + case TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND: + // we use this as a check for friendship, so this can be an expected result + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_By_Public_Key error code:" << error; + return false; + } +} + +bool parseToxErrBootstrap(Tox_Err_Bootstrap error, int line) +{ + switch(error) { + case TOX_ERR_BOOTSTRAP_OK: + return true; + + case TOX_ERR_BOOTSTRAP_NULL: + qCritical() << line << "null argument when not expected"; + return false; + + case TOX_ERR_BOOTSTRAP_BAD_HOST: + qCritical() << line << "Could not resolve hostname, or invalid IP address"; + return false; + + case TOX_ERR_BOOTSTRAP_BAD_PORT: + qCritical() << line << "out of range port"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_bootstrap error code:" << error; + return false; + } +} + +bool parseToxErrFriendAdd(Tox_Err_Friend_Add error, int line) +{ + switch(error) { + case TOX_ERR_FRIEND_ADD_OK: + return true; + + case TOX_ERR_FRIEND_ADD_NULL: + qCritical() << line << "null argument when not expected"; + return false; + + case TOX_ERR_FRIEND_ADD_TOO_LONG: + qCritical() << line << "The length of the friend request message exceeded"; + return false; + + case TOX_ERR_FRIEND_ADD_NO_MESSAGE: + qCritical() << line << "The friend request message was empty."; + return false; + + case TOX_ERR_FRIEND_ADD_OWN_KEY: + qCritical() << line << "The friend address belongs to the sending client."; + return false; + + case TOX_ERR_FRIEND_ADD_ALREADY_SENT: + qCritical() << line << "The address belongs to a friend that is already on the friend list."; + return false; + + case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM: + qCritical() << line << "The friend address checksum failed."; + return false; + + case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM: + qCritical() << line << "The address belongs to a friend that is already on the friend list."; + return false; + + case TOX_ERR_FRIEND_ADD_MALLOC: + qCritical() << line << "A memory allocation failed when trying to increase the friend list size."; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_Add error code:" << error; + return false; + + } +} + +bool parseToxErrFriendDelete(Tox_Err_Friend_Delete error, int line) +{ + switch(error) { + case TOX_ERR_FRIEND_DELETE_OK: + return true; + + case TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND: + qCritical() << line << "There is no friend with the given friend number"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_Delete error code:" << error; + return false; + } +} + +bool parseToxErrSetInfo(Tox_Err_Set_Info error, int line) +{ + switch (error) { + case TOX_ERR_SET_INFO_OK: + return true; + + case TOX_ERR_SET_INFO_NULL: + qCritical() << line << "null argument when not expected"; + return false; + + case TOX_ERR_SET_INFO_TOO_LONG: + qCritical() << line << "Information length exceeded maximum permissible size."; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Set_Info error code:" << error; + return false; + } +} + +bool parseToxErrFriendQuery(Tox_Err_Friend_Query error, int line) +{ + switch (error) { + case TOX_ERR_FRIEND_QUERY_OK: + return true; + + case TOX_ERR_FRIEND_QUERY_NULL: + qCritical() << line << "null argument when not expected"; + return false; + + case TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND: + qCritical() << line << "The friend_number did not designate a valid friend."; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_Query error code:" << error; + return false; + } +} + +bool parseToxErrFriendGetPublicKey(Tox_Err_Friend_Get_Public_Key error, int line) +{ + switch (error) { + case TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK: + return true; + + case TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND: + qCritical() << line << "There is no friend with the given friend number"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_Get_Public_Key error code:" << error; + return false; + } +} + +bool parseToxErrFriendGetLastOnline(Tox_Err_Friend_Get_Last_Online error, int line) +{ + switch (error) { + case TOX_ERR_FRIEND_GET_LAST_ONLINE_OK: + return true; + + case TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND: + qCritical() << line << "There is no friend with the given friend number"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Friend_Get_Last_Online error code:" << error; + return false; + } +} + +bool parseToxErrSetTyping(Tox_Err_Set_Typing error, int line) +{ + switch (error) { + case TOX_ERR_SET_TYPING_OK: + return true; + + case TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND: + qCritical() << line << "There is no friend with the given friend number"; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Set_Typing error code:" << error; + return false; + } +} + +bool parseToxErrConferenceDelete(Tox_Err_Conference_Delete error, int line) +{ + switch (error) { + case TOX_ERR_CONFERENCE_DELETE_OK: + return true; + + case TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND: + qCritical() << line << "The conference number passed did not designate a valid conference."; + return false; + + default: + qCritical() << line << "Unknown Tox_Err_Conference_Delete error code:" << error; + return false; + } +} + } // namespace Core::Core(QThread* coreThread) @@ -526,11 +805,14 @@ void Core::bootstrapDht() const uint8_t* pkPtr = pk.getData(); - if (!tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) { + Tox_Err_Bootstrap error; + tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, &error); + if (!PARSE_ERR(ToxErrBootstrap, error)) { qDebug() << "Error bootstrapping from " + dhtServer.name; } - if (!tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) { + tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, pkPtr, &error); + if (!PARSE_ERR(ToxErrBootstrap, error)) { qDebug() << "Error adding TCP relay from " + dhtServer.name; } @@ -675,13 +957,13 @@ void Core::onReadReceiptCallback(Tox*, uint32_t friendId, uint32_t receipt, void void Core::acceptFriendRequest(const ToxPk& friendPk) { QMutexLocker ml{&coreLoopLock}; - // TODO: error handling - uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getData(), nullptr); - if (friendId == std::numeric_limits::max()) { - emit failedToAddFriend(friendPk); - } else { + Tox_Err_Friend_Add error; + uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getData(), &error); + if (PARSE_ERR(ToxErrFriendAdd, error)) { emit saveRequest(); emit friendAdded(friendId, friendPk); + } else { + emit failedToAddFriend(friendPk); } } @@ -728,18 +1010,18 @@ void Core::requestFriendship(const ToxId& friendId, const QString& message) } ToxString cMessage(message); + Tox_Err_Friend_Add error; uint32_t friendNumber = - tox_friend_add(tox.get(), friendId.getBytes(), cMessage.data(), cMessage.size(), nullptr); - if (friendNumber == std::numeric_limits::max()) { - qDebug() << "Failed to send friend request"; - emit failedToAddFriend(friendPk); - } else { + tox_friend_add(tox.get(), friendId.getBytes(), cMessage.data(), cMessage.size(), &error); + if (PARSE_ERR(ToxErrFriendAdd, error)) { qDebug() << "Requested friendship from " << friendNumber; + emit saveRequest(); emit friendAdded(friendNumber, friendPk); emit requestSent(friendPk, message); + } else { + qDebug() << "Failed to send friend request"; + emit failedToAddFriend(friendPk); } - - emit saveRequest(); } bool Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type, @@ -757,7 +1039,7 @@ bool Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Me Tox_Err_Friend_Send_Message error; receipt = ReceiptNum{tox_friend_send_message(tox.get(), friendId, type, cMessage.data(), cMessage.size(), &error)}; - if (parseFriendSendMessageError(error)) { + if (PARSE_ERR(ToxErrFriendSendMessage, error)) { return true; } return false; @@ -779,7 +1061,9 @@ void Core::sendTyping(uint32_t friendId, bool typing) { QMutexLocker ml{&coreLoopLock}; - if (!tox_self_set_typing(tox.get(), friendId, typing, nullptr)) { + Tox_Err_Set_Typing error; + tox_self_set_typing(tox.get(), friendId, typing, &error); + if (!PARSE_ERR(ToxErrSetTyping, error)) { emit failedToSetTyping(typing); } } @@ -799,7 +1083,7 @@ void Core::sendGroupMessageWithType(int groupId, const QString& message, Tox_Mes ToxString cMsg(message); Tox_Err_Conference_Send_Message error; tox_conference_send_message(tox.get(), groupId, type, cMsg.data(), cMsg.size(), &error); - if (!parseConferenceSendMessageError(error)) { + if (!PARSE_ERR(ToxErrConferenceSendMessage, error)) { emit groupSentFailed(groupId); return; } @@ -825,29 +1109,10 @@ void Core::changeGroupTitle(int groupId, const QString& title) ToxString cTitle(title); Tox_Err_Conference_Title error; - bool success = tox_conference_set_title(tox.get(), groupId, cTitle.data(), cTitle.size(), &error); - if (success && error == TOX_ERR_CONFERENCE_TITLE_OK) { + tox_conference_set_title(tox.get(), groupId, cTitle.data(), cTitle.size(), &error); + if (PARSE_ERR(ToxErrConferenceTitle, error)) { emit saveRequest(); emit groupTitleChanged(groupId, getUsername(), title); - return; - } - - qCritical() << "Fail of tox_conference_set_title"; - switch (error) { - case TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND: - qCritical() << "Conference not found"; - break; - - case TOX_ERR_CONFERENCE_TITLE_FAIL_SEND: - qCritical() << "Conference title failed to send"; - break; - - case TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH: - qCritical() << "Invalid length"; - break; - - default: - break; } } @@ -855,7 +1120,9 @@ void Core::removeFriend(uint32_t friendId) { QMutexLocker ml{&coreLoopLock}; - if (!tox_friend_delete(tox.get(), friendId, nullptr)) { + Tox_Err_Friend_Delete error; + tox_friend_delete(tox.get(), friendId, &error); + if (!PARSE_ERR(ToxErrFriendDelete, error)) { emit failedToRemoveFriend(friendId); return; } @@ -869,21 +1136,10 @@ void Core::removeGroup(int groupId) QMutexLocker ml{&coreLoopLock}; Tox_Err_Conference_Delete error; - bool success = tox_conference_delete(tox.get(), groupId, &error); - if (success && error == TOX_ERR_CONFERENCE_DELETE_OK) { + tox_conference_delete(tox.get(), groupId, &error); + if (PARSE_ERR(ToxErrConferenceDelete, error)) { emit saveRequest(); av->leaveGroupCall(groupId); - return; - } - - qCritical() << "Fail of tox_conference_delete"; - switch (error) { - case TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND: - qCritical() << "Conference not found"; - break; - - default: - break; } } @@ -916,7 +1172,9 @@ void Core::setUsername(const QString& username) } ToxString cUsername(username); - if (!tox_self_set_name(tox.get(), cUsername.data(), cUsername.size(), nullptr)) { + Tox_Err_Set_Info error; + tox_self_set_name(tox.get(), cUsername.data(), cUsername.size(), &error); + if (!PARSE_ERR(ToxErrSetInfo, error)) { emit failedToSetUsername(username); return; } @@ -1008,7 +1266,9 @@ void Core::setStatusMessage(const QString& message) } ToxString cMessage(message); - if (!tox_self_set_status_message(tox.get(), cMessage.data(), cMessage.size(), nullptr)) { + Tox_Err_Set_Info error; + tox_self_set_status_message(tox.get(), cMessage.data(), cMessage.size(), &error); + if (!PARSE_ERR(ToxErrSetInfo, error)) { emit failedToSetStatusMessage(message); return; } @@ -1059,19 +1319,6 @@ QByteArray Core::getToxSaveData() return data; } -// Declared to avoid code duplication -#define GET_FRIEND_PROPERTY(property, function, checkSize) \ - const size_t property##Size = function##_size(tox.get(), ids[i], nullptr); \ - if ((!checkSize || property##Size) && property##Size != SIZE_MAX) { \ - uint8_t* prop = new uint8_t[property##Size]; \ - if (function(tox.get(), ids[i], prop, nullptr)) { \ - QString propStr = ToxString(prop, property##Size).getQString(); \ - emit friend##property##Changed(ids[i], propStr); \ - } \ - \ - delete[] prop; \ - } - void Core::loadFriends() { QMutexLocker ml{&coreLoopLock}; @@ -1085,13 +1332,21 @@ void Core::loadFriends() tox_self_get_friend_list(tox.get(), ids); uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; for (size_t i = 0; i < friendCount; ++i) { - if (!tox_friend_get_public_key(tox.get(), ids[i], friendPk, nullptr)) { + Tox_Err_Friend_Get_Public_Key keyError; + tox_friend_get_public_key(tox.get(), ids[i], friendPk, &keyError); + if (!PARSE_ERR(ToxErrFriendGetPublicKey, keyError)) { continue; } - emit friendAdded(ids[i], ToxPk(friendPk)); - GET_FRIEND_PROPERTY(Username, tox_friend_get_name, true); - GET_FRIEND_PROPERTY(StatusMessage, tox_friend_get_status_message, false); + emit friendUsernameChanged(ids[i], getFriendUsername(ids[i])); + Tox_Err_Friend_Query queryError; + size_t statusMessageSize = tox_friend_get_status_message_size(tox.get(), ids[i], &queryError); + if (PARSE_ERR(ToxErrFriendQuery, queryError)) { + std::vector messageData(statusMessageSize); + tox_friend_get_status_message(tox.get(), ids[i], messageData.data(), &queryError); + QString friendStatusMessage = ToxString(messageData.data(), statusMessageSize).getQString(); + emit friendStatusMessageChanged(ids[i], friendStatusMessage); + } checkLastOnline(ids[i]); } delete[] ids; @@ -1110,23 +1365,23 @@ void Core::loadGroups() tox_conference_get_chatlist(tox.get(), groupNumbers); for (size_t i = 0; i < groupCount; ++i) { - TOX_ERR_CONFERENCE_TITLE error; + Tox_Err_Conference_Title error; QString name; const auto groupNumber = groupNumbers[i]; size_t titleSize = tox_conference_get_title_size(tox.get(), groupNumber, &error); const GroupId persistentId = getGroupPersistentId(groupNumber); const QString defaultName = tr("Groupchat %1").arg(persistentId.toString().left(8)); - if (LogConferenceTitleError(error)) { - name = defaultName; - } else { + if (PARSE_ERR(ToxErrConferenceTitle, error)) { QByteArray nameByteArray = QByteArray(static_cast(titleSize), Qt::Uninitialized); tox_conference_get_title(tox.get(), groupNumber, reinterpret_cast(nameByteArray.data()), &error); - if (LogConferenceTitleError(error)) { - name = defaultName; - } else { + if (PARSE_ERR(ToxErrConferenceTitle, error)) { name = ToxString(nameByteArray).getQString(); + } else { + name = defaultName; } + } else { + name = defaultName; } if (getGroupAvEnabled(groupNumber)) { if (toxav_groupchat_enable_av(tox.get(), groupNumber, CoreAV::groupCallCallback, this)) { @@ -1143,8 +1398,9 @@ void Core::checkLastOnline(uint32_t friendId) { QMutexLocker ml{&coreLoopLock}; - const uint64_t lastOnline = tox_friend_get_last_online(tox.get(), friendId, nullptr); - if (lastOnline != std::numeric_limits::max()) { + Tox_Err_Friend_Get_Last_Online error; + const uint64_t lastOnline = tox_friend_get_last_online(tox.get(), friendId, &error); + if (PARSE_ERR(ToxErrFriendGetLastOnline, error)) { emit friendLastSeenChanged(friendId, QDateTime::fromTime_t(lastOnline)); } } @@ -1187,7 +1443,7 @@ uint32_t Core::getGroupNumberPeers(int groupId) const Tox_Err_Conference_Peer_Query error; uint32_t count = tox_conference_peer_count(tox.get(), groupId, &error); - if (!parsePeerQueryError(error)) { + if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) { return std::numeric_limits::max(); } @@ -1203,14 +1459,14 @@ QString Core::getGroupPeerName(int groupId, int peerId) const Tox_Err_Conference_Peer_Query error; size_t length = tox_conference_peer_get_name_size(tox.get(), groupId, peerId, &error); - if (!parsePeerQueryError(error)) { + if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) { return QString{}; } QByteArray name(length, Qt::Uninitialized); uint8_t* namePtr = reinterpret_cast(name.data()); bool success = tox_conference_peer_get_name(tox.get(), groupId, peerId, namePtr, &error); - if (!parsePeerQueryError(error)) { + if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) { return QString{}; } assert(success); @@ -1228,7 +1484,7 @@ ToxPk Core::getGroupPeerPk(int groupId, int peerId) const uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; Tox_Err_Conference_Peer_Query error; bool success = tox_conference_peer_get_public_key(tox.get(), groupId, peerId, friendPk, &error); - if (!parsePeerQueryError(error)) { + if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) { return ToxPk{}; } assert(success); @@ -1253,16 +1509,16 @@ QStringList Core::getGroupPeerNames(int groupId) const QStringList names; for (uint32_t i = 0; i < nPeers; ++i) { - TOX_ERR_CONFERENCE_PEER_QUERY error; + Tox_Err_Conference_Peer_Query error; size_t length = tox_conference_peer_get_name_size(tox.get(), groupId, i, &error); - if (!parsePeerQueryError(error)) { + if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) { continue; } QByteArray name(length, Qt::Uninitialized); uint8_t* namePtr = reinterpret_cast(name.data()); bool ok = tox_conference_peer_get_name(tox.get(), groupId, i, namePtr, &error); - if (ok && parsePeerQueryError(error)) { + if (ok && PARSE_ERR(ToxErrConferencePeerQuery, error)) { names.append(ToxString(name).getQString()); } } @@ -1278,19 +1534,10 @@ QStringList Core::getGroupPeerNames(int groupId) const bool Core::getGroupAvEnabled(int groupId) const { QMutexLocker ml{&coreLoopLock}; - TOX_ERR_CONFERENCE_GET_TYPE error; - TOX_CONFERENCE_TYPE type = tox_conference_get_type(tox.get(), groupId, &error); - switch (error) { - case TOX_ERR_CONFERENCE_GET_TYPE_OK: - break; - case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND: - qWarning() << "Conference not found"; - break; - default: - qWarning() << "Unknown error code:" << QString::number(error); - break; - } - + Tox_Err_Conference_Get_Type error; + Tox_Conference_Type type = tox_conference_get_type(tox.get(), groupId, &error); + PARSE_ERR(ToxErrConferenceGetType, error); + // would be nice to indicate to caller that we don't actually know.. return type == TOX_CONFERENCE_TYPE_AV; } @@ -1315,7 +1562,7 @@ uint32_t Core::joinGroupchat(const GroupInvite& inviteInfo) qDebug() << QString("Trying to accept invite for text group chat sent by friend %1").arg(friendId); Tox_Err_Conference_Join error; groupNum = tox_conference_join(tox.get(), friendId, cookie, cookieLength, &error); - if (!parseConferenceJoinError(error)) { + if (!PARSE_ERR(ToxErrConferenceJoin, error)) { groupNum = std::numeric_limits::max(); } break; @@ -1342,22 +1589,7 @@ void Core::groupInviteFriend(uint32_t friendId, int groupId) Tox_Err_Conference_Invite error; tox_conference_invite(tox.get(), friendId, groupId, &error); - - switch (error) { - case TOX_ERR_CONFERENCE_INVITE_OK: - break; - - case TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND: - qCritical() << "Conference not found"; - break; - - case TOX_ERR_CONFERENCE_INVITE_FAIL_SEND: - qCritical() << "Conference invite failed to send"; - break; - - default: - break; - } + PARSE_ERR(ToxErrConferenceInvite, error); } int Core::createGroup(uint8_t type) @@ -1367,24 +1599,23 @@ int Core::createGroup(uint8_t type) if (type == TOX_CONFERENCE_TYPE_TEXT) { Tox_Err_Conference_New error; uint32_t groupId = tox_conference_new(tox.get(), &error); - - switch (error) { - case TOX_ERR_CONFERENCE_NEW_OK: + if (PARSE_ERR(ToxErrConferenceNew, error)) { emit saveRequest(); emit emptyGroupCreated(groupId, getGroupPersistentId(groupId)); return groupId; - - case TOX_ERR_CONFERENCE_NEW_INIT: - qCritical() << "The conference instance failed to initialize"; - return std::numeric_limits::max(); - - default: + } else { return std::numeric_limits::max(); } } else if (type == TOX_CONFERENCE_TYPE_AV) { - uint32_t groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this); - emit saveRequest(); - emit emptyGroupCreated(groupId, getGroupPersistentId(groupId)); + // unlike tox_conference_new, toxav_add_av_groupchat does not have an error enum, so -1 group number is our + // only indication of an error + int groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this); + if (groupId != -1) { + emit saveRequest(); + emit emptyGroupCreated(groupId, getGroupPersistentId(groupId)); + } else { + qCritical() << "Unknown error creating AV groupchat"; + } return groupId; } else { qWarning() << "createGroup: Unknown type " << type; @@ -1399,7 +1630,9 @@ bool Core::isFriendOnline(uint32_t friendId) const { QMutexLocker ml{&coreLoopLock}; - Tox_Connection connection = tox_friend_get_connection_status(tox.get(), friendId, nullptr); + Tox_Err_Friend_Query error; + Tox_Connection connection = tox_friend_get_connection_status(tox.get(), friendId, &error); + PARSE_ERR(ToxErrFriendQuery, error); return connection != TOX_CONNECTION_NONE; } @@ -1414,9 +1647,9 @@ bool Core::hasFriendWithPublicKey(const ToxPk& publicKey) const return false; } - // TODO: error handling - uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getData(), nullptr); - return friendId != std::numeric_limits::max(); + Tox_Err_Friend_By_Public_Key error; + uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getData(), &error); + return PARSE_ERR(ToxErrFriendByPublicKey, error); } /** @@ -1427,7 +1660,9 @@ ToxPk Core::getFriendPublicKey(uint32_t friendNumber) const QMutexLocker ml{&coreLoopLock}; uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; - if (!tox_friend_get_public_key(tox.get(), friendNumber, rawid, nullptr)) { + Tox_Err_Friend_Get_Public_Key error; + tox_friend_get_public_key(tox.get(), friendNumber, rawid, &error); + if (!PARSE_ERR(ToxErrFriendGetPublicKey, error)) { qWarning() << "getFriendPublicKey: Getting public key failed"; return ToxPk(); } @@ -1442,14 +1677,20 @@ QString Core::getFriendUsername(uint32_t friendnumber) const { QMutexLocker ml{&coreLoopLock}; - size_t namesize = tox_friend_get_name_size(tox.get(), friendnumber, nullptr); - if (namesize == SIZE_MAX) { + Tox_Err_Friend_Query error; + size_t namesize = tox_friend_get_name_size(tox.get(), friendnumber, &error); + if (!PARSE_ERR(ToxErrFriendQuery, error)) { qWarning() << "getFriendUsername: Failed to get name size for friend " << friendnumber; return QString(); } uint8_t* name = new uint8_t[namesize]; - tox_friend_get_name(tox.get(), friendnumber, name, nullptr); + tox_friend_get_name(tox.get(), friendnumber, name, &error); + if (!PARSE_ERR(ToxErrFriendQuery, error)) { + qWarning() << "getFriendUsername: Failed to get name of friend " << friendnumber; + delete[] name; + return QString(); + } ToxString sname(name, namesize); delete[] name; return sname.getQString(); @@ -1504,19 +1745,22 @@ QString Core::getPeerName(const ToxPk& id) const QMutexLocker ml{&coreLoopLock}; QString name; - uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getData(), nullptr); - if (friendId == std::numeric_limits::max()) { + Tox_Err_Friend_By_Public_Key keyError; + uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getData(), &keyError); + if (!PARSE_ERR(ToxErrFriendByPublicKey, keyError)) { qWarning() << "getPeerName: No such peer"; return name; } - const size_t nameSize = tox_friend_get_name_size(tox.get(), friendId, nullptr); - if (nameSize == SIZE_MAX) { + Tox_Err_Friend_Query queryError; + const size_t nameSize = tox_friend_get_name_size(tox.get(), friendId, &queryError); + if (!PARSE_ERR(ToxErrFriendQuery, queryError)) { return name; } uint8_t* cname = new uint8_t[nameSize < tox_max_name_length() ? tox_max_name_length() : nameSize]; - if (!tox_friend_get_name(tox.get(), friendId, cname, nullptr)) { + tox_friend_get_name(tox.get(), friendId, cname, &queryError); + if (!PARSE_ERR(ToxErrFriendQuery, queryError)) { qWarning() << "getPeerName: Can't get name of friend " + QString().setNum(friendId); delete[] cname; return name;