feat: improve create clip error messaging (#5879)
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
- Minor: Remove incognito browser support for `iexplore`, because internet explorer is EOL. (#5810)
|
||||
- Minor: When (re-)connecting, visible channels are now joined first. (#5850)
|
||||
- Minor: Added the ability to filter on messages by the author's user ID (example: `author.user_id == "22484632"`). (#5862)
|
||||
- Minor: Improved error messaging of the `/clip` command. (#5879)
|
||||
- Bugfix: Fixed a potential way to escape the Lua Plugin sandbox. (#5846)
|
||||
- Bugfix: Fixed a crash relating to Lua HTTP. (#5800)
|
||||
- Bugfix: Fixed a crash that could occur on Linux and macOS when clicking "Install" from the update prompt. (#5818)
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
|
||||
MOCK_METHOD(void, createClip,
|
||||
(QString channelId, ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError)> failureCallback,
|
||||
std::function<void(HelixClipError, QString)> failureCallback,
|
||||
std::function<void()> finallyCallback),
|
||||
(override));
|
||||
|
||||
|
||||
@@ -67,13 +67,21 @@ namespace {
|
||||
#endif
|
||||
constexpr int CLIP_CREATION_COOLDOWN = 5000;
|
||||
const QString CLIPS_LINK("https://clips.twitch.tv/%1");
|
||||
const QString CLIPS_FAILURE_CLIPS_UNAVAILABLE_TEXT(
|
||||
"Failed to create a clip - clips are temporarily unavailable: %1");
|
||||
const QString CLIPS_FAILURE_CLIPS_DISABLED_TEXT(
|
||||
"Failed to create a clip - the streamer has clips disabled entirely or "
|
||||
"requires a certain subscriber or follower status to create clips.");
|
||||
"Failed to create a clip - the streamer has clips disabled in their "
|
||||
"channel.");
|
||||
const QString CLIPS_FAILURE_CLIPS_RESTRICTED_TEXT(
|
||||
"Failed to create a clip - the streamer has restricted clip creation "
|
||||
"to subscribers, or followers of an unknown duration.");
|
||||
const QString CLIPS_FAILURE_CLIPS_RESTRICTED_CATEGORY_TEXT(
|
||||
"Failed to create a clip - the streamer has disabled clips while in "
|
||||
"this category.");
|
||||
const QString CLIPS_FAILURE_NOT_AUTHENTICATED_TEXT(
|
||||
"Failed to create a clip - you need to re-authenticate.");
|
||||
const QString CLIPS_FAILURE_UNKNOWN_ERROR_TEXT(
|
||||
"Failed to create a clip - an unknown error occurred.");
|
||||
"Failed to create a clip: %1");
|
||||
const QString LOGIN_PROMPT_TEXT("Click here to add your account again.");
|
||||
const Link ACCOUNTS_LINK(Link::OpenAccountsPage, QString());
|
||||
|
||||
@@ -1771,7 +1779,7 @@ void TwitchChannel::createClip()
|
||||
this->addMessage(builder.release(), MessageContext::Original);
|
||||
},
|
||||
// failureCallback
|
||||
[this](auto error) {
|
||||
[this](auto error, auto errorMessage) {
|
||||
MessageBuilder builder;
|
||||
QString text;
|
||||
builder.message().flags.set(MessageFlag::System);
|
||||
@@ -1780,6 +1788,15 @@ void TwitchChannel::createClip()
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case HelixClipError::ClipsUnavailable: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_CLIPS_UNAVAILABLE_TEXT.arg(errorMessage),
|
||||
MessageElementFlag::Text, MessageColor::System);
|
||||
text =
|
||||
CLIPS_FAILURE_CLIPS_UNAVAILABLE_TEXT.arg(errorMessage);
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixClipError::ClipsDisabled: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_CLIPS_DISABLED_TEXT,
|
||||
@@ -1788,6 +1805,22 @@ void TwitchChannel::createClip()
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixClipError::ClipsRestricted: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_CLIPS_RESTRICTED_TEXT,
|
||||
MessageElementFlag::Text, MessageColor::System);
|
||||
text = CLIPS_FAILURE_CLIPS_RESTRICTED_TEXT;
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixClipError::ClipsRestrictedCategory: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_CLIPS_RESTRICTED_CATEGORY_TEXT,
|
||||
MessageElementFlag::Text, MessageColor::System);
|
||||
text = CLIPS_FAILURE_CLIPS_RESTRICTED_CATEGORY_TEXT;
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixClipError::UserNotAuthenticated: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_NOT_AUTHENTICATED_TEXT,
|
||||
@@ -1807,9 +1840,9 @@ void TwitchChannel::createClip()
|
||||
case HelixClipError::Unknown:
|
||||
default: {
|
||||
builder.emplace<TextElement>(
|
||||
CLIPS_FAILURE_UNKNOWN_ERROR_TEXT,
|
||||
CLIPS_FAILURE_UNKNOWN_ERROR_TEXT.arg(errorMessage),
|
||||
MessageElementFlag::Text, MessageColor::System);
|
||||
text = CLIPS_FAILURE_UNKNOWN_ERROR_TEXT;
|
||||
text = CLIPS_FAILURE_UNKNOWN_ERROR_TEXT.arg(errorMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -351,10 +351,10 @@ void Helix::getGameById(QString gameId,
|
||||
failureCallback);
|
||||
}
|
||||
|
||||
void Helix::createClip(QString channelId,
|
||||
ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError)> failureCallback,
|
||||
std::function<void()> finallyCallback)
|
||||
void Helix::createClip(
|
||||
QString channelId, ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError, QString)> failureCallback,
|
||||
std::function<void()> finallyCallback)
|
||||
{
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem("broadcaster_id", channelId);
|
||||
@@ -367,7 +367,7 @@ void Helix::createClip(QString channelId,
|
||||
|
||||
if (!data.isArray())
|
||||
{
|
||||
failureCallback(HelixClipError::Unknown);
|
||||
failureCallback(HelixClipError::Unknown, "No clip was created");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -376,17 +376,45 @@ void Helix::createClip(QString channelId,
|
||||
successCallback(clip);
|
||||
})
|
||||
.onError([failureCallback](auto result) {
|
||||
auto obj = result.parseJson();
|
||||
auto message = obj.value("message").toString();
|
||||
switch (result.status().value_or(0))
|
||||
{
|
||||
case 503: {
|
||||
// Channel has disabled clip-creation, or channel has made cliops only creatable by followers and the user is not a follower (or subscriber)
|
||||
failureCallback(HelixClipError::ClipsDisabled);
|
||||
// We should not necessarily handle this, so the error messaging will use `message` if it exists
|
||||
failureCallback(HelixClipError::ClipsUnavailable, message);
|
||||
}
|
||||
break;
|
||||
|
||||
case 401: {
|
||||
// User does not have the required scope to be able to create clips, user must reauthenticate
|
||||
failureCallback(HelixClipError::UserNotAuthenticated);
|
||||
failureCallback(HelixClipError::UserNotAuthenticated,
|
||||
message);
|
||||
}
|
||||
break;
|
||||
|
||||
case 403: {
|
||||
if (message.contains("restricted for this channel"))
|
||||
{
|
||||
failureCallback(HelixClipError::ClipsDisabled, message);
|
||||
}
|
||||
else if (message.contains("User does not have permissions"))
|
||||
{
|
||||
failureCallback(HelixClipError::ClipsRestricted,
|
||||
message);
|
||||
}
|
||||
else if (message.contains("restricted for this category"))
|
||||
{
|
||||
failureCallback(HelixClipError::ClipsRestrictedCategory,
|
||||
message);
|
||||
}
|
||||
else
|
||||
{
|
||||
qCDebug(chatterinoTwitch)
|
||||
<< "Failed to create a clip: "
|
||||
<< result.formatError() << result.getData();
|
||||
failureCallback(HelixClipError::Unknown, message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -394,7 +422,7 @@ void Helix::createClip(QString channelId,
|
||||
qCDebug(chatterinoTwitch)
|
||||
<< "Failed to create a clip: " << result.formatError()
|
||||
<< result.getData();
|
||||
failureCallback(HelixClipError::Unknown);
|
||||
failureCallback(HelixClipError::Unknown, message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -474,7 +474,10 @@ enum class HelixAnnouncementColor {
|
||||
|
||||
enum class HelixClipError {
|
||||
Unknown,
|
||||
ClipsUnavailable,
|
||||
ClipsDisabled,
|
||||
ClipsRestricted,
|
||||
ClipsRestrictedCategory,
|
||||
UserNotAuthenticated,
|
||||
};
|
||||
|
||||
@@ -864,10 +867,10 @@ public:
|
||||
HelixFailureCallback failureCallback) = 0;
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#create-clip
|
||||
virtual void createClip(QString channelId,
|
||||
ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError)> failureCallback,
|
||||
std::function<void()> finallyCallback) = 0;
|
||||
virtual void createClip(
|
||||
QString channelId, ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError, QString)> failureCallback,
|
||||
std::function<void()> finallyCallback) = 0;
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#get-channel-information
|
||||
virtual void fetchChannels(
|
||||
@@ -1207,10 +1210,10 @@ public:
|
||||
HelixFailureCallback failureCallback) final;
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#create-clip
|
||||
void createClip(QString channelId,
|
||||
ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError)> failureCallback,
|
||||
std::function<void()> finallyCallback) final;
|
||||
void createClip(
|
||||
QString channelId, ResultCallback<HelixClip> successCallback,
|
||||
std::function<void(HelixClipError, QString)> failureCallback,
|
||||
std::function<void()> finallyCallback) final;
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#get-channel-information
|
||||
void fetchChannels(
|
||||
|
||||
Reference in New Issue
Block a user