Skip to content

Commit 38064be

Browse files
committed
Add more specific error messages and deduplicate their handling
1 parent d17eae9 commit 38064be

8 files changed

Lines changed: 52 additions & 79 deletions

File tree

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ dependencies {
214214
// the corresponding commit hash, since JitPack sometimes deletes artifacts.
215215
// If there’s already a git hash, just add more of it to the end (or remove a letter)
216216
// to cause jitpack to regenerate the artifact.
217-
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.8'
217+
implementation 'com.github.Stypox:NewPipeExtractor:b8bd4cda8cca00a14940933e3d3635d5aafec222'
218218
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
219219

220220
/** Checkstyle **/

app/src/main/java/org/schabi/newpipe/RouterActivity.java

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,13 @@
5858
import org.schabi.newpipe.extractor.StreamingService;
5959
import org.schabi.newpipe.extractor.StreamingService.LinkType;
6060
import org.schabi.newpipe.extractor.channel.ChannelInfo;
61-
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException;
6261
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
6362
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
6463
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
65-
import org.schabi.newpipe.extractor.exceptions.GeographicRestrictionException;
66-
import org.schabi.newpipe.extractor.exceptions.PaidContentException;
67-
import org.schabi.newpipe.extractor.exceptions.PrivateContentException;
6864
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
69-
import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException;
70-
import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException;
7165
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
7266
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
7367
import org.schabi.newpipe.extractor.stream.StreamInfo;
74-
import org.schabi.newpipe.ktx.ExceptionUtils;
7568
import org.schabi.newpipe.local.dialog.PlaylistDialog;
7669
import org.schabi.newpipe.player.PlayerType;
7770
import org.schabi.newpipe.player.helper.PlayerHelper;
@@ -279,28 +272,11 @@ private static void handleError(final Context context, final ErrorInfo errorInfo
279272
final Intent intent = new Intent(context, ReCaptchaActivity.class);
280273
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
281274
context.startActivity(intent);
282-
} else if (errorInfo.getThrowable() != null
283-
&& ExceptionUtils.isNetworkRelated(errorInfo.getThrowable())) {
284-
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
285-
} else if (errorInfo.getThrowable() instanceof AgeRestrictedContentException) {
286-
Toast.makeText(context, R.string.restricted_video_no_stream,
287-
Toast.LENGTH_LONG).show();
288-
} else if (errorInfo.getThrowable() instanceof GeographicRestrictionException) {
289-
Toast.makeText(context, R.string.georestricted_content, Toast.LENGTH_LONG).show();
290-
} else if (errorInfo.getThrowable() instanceof PaidContentException) {
291-
Toast.makeText(context, R.string.paid_content, Toast.LENGTH_LONG).show();
292-
} else if (errorInfo.getThrowable() instanceof PrivateContentException) {
293-
Toast.makeText(context, R.string.private_content, Toast.LENGTH_LONG).show();
294-
} else if (errorInfo.getThrowable() instanceof SoundCloudGoPlusContentException) {
295-
Toast.makeText(context, R.string.soundcloud_go_plus_content,
296-
Toast.LENGTH_LONG).show();
297-
} else if (errorInfo.getThrowable() instanceof YoutubeMusicPremiumContentException) {
298-
Toast.makeText(context, R.string.youtube_music_premium_content,
299-
Toast.LENGTH_LONG).show();
300-
} else if (errorInfo.getThrowable() instanceof ContentNotAvailableException) {
301-
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
302-
} else if (errorInfo.getThrowable() instanceof ContentNotSupportedException) {
303-
Toast.makeText(context, R.string.content_not_supported, Toast.LENGTH_LONG).show();
275+
} else if (errorInfo.getThrowable() instanceof ContentNotAvailableException
276+
|| errorInfo.getThrowable() instanceof ContentNotSupportedException) {
277+
// this exception does not usually indicate a problem that should be reported,
278+
// so just show a toast instead of the notification
279+
Toast.makeText(context, errorInfo.getMessageStringId(), Toast.LENGTH_LONG).show();
304280
} else {
305281
ErrorUtil.createNotification(context, errorInfo);
306282
}

app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,25 @@ package org.schabi.newpipe.error
33
import android.os.Parcelable
44
import androidx.annotation.StringRes
55
import com.google.android.exoplayer2.ExoPlaybackException
6+
import com.google.android.exoplayer2.upstream.HttpDataSource
7+
import com.google.android.exoplayer2.upstream.Loader
68
import kotlinx.parcelize.IgnoredOnParcel
79
import kotlinx.parcelize.Parcelize
810
import org.schabi.newpipe.R
911
import org.schabi.newpipe.extractor.Info
1012
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException
13+
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException
1114
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
1215
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException
1316
import org.schabi.newpipe.extractor.exceptions.ExtractionException
17+
import org.schabi.newpipe.extractor.exceptions.GeographicRestrictionException
18+
import org.schabi.newpipe.extractor.exceptions.PaidContentException
19+
import org.schabi.newpipe.extractor.exceptions.PrivateContentException
20+
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
21+
import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException
22+
import org.schabi.newpipe.extractor.exceptions.UnsupportedContentInCountryException
23+
import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException
24+
import org.schabi.newpipe.extractor.exceptions.YoutubeSignInConfirmNotBotException
1425
import org.schabi.newpipe.ktx.isNetworkRelated
1526
import org.schabi.newpipe.util.ServiceHelper
1627

@@ -91,25 +102,44 @@ class ErrorInfo(
91102
action: UserAction
92103
): Int {
93104
return when {
105+
// content not available exceptions
94106
throwable is AccountTerminatedException -> R.string.account_terminated
107+
throwable is AgeRestrictedContentException -> R.string.restricted_video_no_stream
108+
throwable is GeographicRestrictionException -> R.string.georestricted_content
109+
throwable is PaidContentException -> R.string.paid_content
110+
throwable is PrivateContentException -> R.string.private_content
111+
throwable is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
112+
throwable is UnsupportedContentInCountryException -> R.string.unsupported_content_in_country
113+
throwable is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
114+
throwable is YoutubeSignInConfirmNotBotException -> R.string.youtube_sign_in_confirm_not_bot_error
95115
throwable is ContentNotAvailableException -> R.string.content_not_available
96-
throwable != null && throwable.isNetworkRelated -> R.string.network_error
116+
117+
// ReCaptchas should have already been handled elsewhere,
118+
// but return an error message here just in case
119+
throwable is ReCaptchaException -> R.string.recaptcha_request_toast
120+
121+
// other extractor exceptions
97122
throwable is ContentNotSupportedException -> R.string.content_not_supported
123+
throwable != null && throwable.isNetworkRelated -> R.string.network_error
98124
throwable is ExtractionException -> R.string.parsing_error
125+
126+
// ExoPlayer exceptions
99127
throwable is ExoPlaybackException -> {
100128
when (throwable.type) {
101129
ExoPlaybackException.TYPE_SOURCE -> R.string.player_stream_failure
102130
ExoPlaybackException.TYPE_UNEXPECTED -> R.string.player_recoverable_failure
103131
else -> R.string.player_unrecoverable_failure
104132
}
105133
}
134+
135+
// user actions (in case the exception is unrecognizable)
106136
action == UserAction.UI_ERROR -> R.string.app_ui_crash
107137
action == UserAction.REQUESTED_COMMENTS -> R.string.error_unable_to_load_comments
108138
action == UserAction.SUBSCRIPTION_CHANGE -> R.string.subscription_change_failed
109139
action == UserAction.SUBSCRIPTION_UPDATE -> R.string.subscription_update_failed
110140
action == UserAction.LOAD_IMAGE -> R.string.could_not_load_thumbnails
111141
action == UserAction.DOWNLOAD_OPEN_DIALOG -> R.string.could_not_setup_download_menu
112-
else -> R.string.general_error
142+
else -> R.string.error_snackbar_message
113143
}
114144
}
115145
}

app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,12 @@ import io.reactivex.rxjava3.disposables.Disposable
1515
import org.schabi.newpipe.MainActivity
1616
import org.schabi.newpipe.R
1717
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException
18-
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException
1918
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
2019
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException
21-
import org.schabi.newpipe.extractor.exceptions.GeographicRestrictionException
22-
import org.schabi.newpipe.extractor.exceptions.PaidContentException
23-
import org.schabi.newpipe.extractor.exceptions.PrivateContentException
2420
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
25-
import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException
26-
import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException
2721
import org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty
2822
import org.schabi.newpipe.ktx.animate
2923
import org.schabi.newpipe.ktx.isInterruptedCaused
30-
import org.schabi.newpipe.ktx.isNetworkRelated
3124
import org.schabi.newpipe.util.ServiceHelper
3225
import org.schabi.newpipe.util.external_communication.ShareUtils
3326
import java.util.concurrent.TimeUnit
@@ -127,7 +120,7 @@ class ErrorPanelHelper(
127120
ErrorUtil.openActivity(context, errorInfo)
128121
}
129122

130-
errorTextView.setText(getExceptionDescription(errorInfo.throwable))
123+
errorTextView.setText(errorInfo.messageStringId)
131124

132125
if (errorInfo.throwable !is ContentNotAvailableException &&
133126
errorInfo.throwable !is ContentNotSupportedException
@@ -192,27 +185,5 @@ class ErrorPanelHelper(
192185
companion object {
193186
val TAG: String = ErrorPanelHelper::class.simpleName!!
194187
val DEBUG: Boolean = MainActivity.DEBUG
195-
196-
@StringRes
197-
fun getExceptionDescription(throwable: Throwable?): Int {
198-
return when (throwable) {
199-
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
200-
is GeographicRestrictionException -> R.string.georestricted_content
201-
is PaidContentException -> R.string.paid_content
202-
is PrivateContentException -> R.string.private_content
203-
is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
204-
is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
205-
is ContentNotAvailableException -> R.string.content_not_available
206-
is ContentNotSupportedException -> R.string.content_not_supported
207-
else -> {
208-
// show retry button only for content which is not unavailable or unsupported
209-
if (throwable != null && throwable.isNetworkRelated) {
210-
R.string.network_error
211-
} else {
212-
R.string.error_snackbar_message
213-
}
214-
}
215-
}
216-
}
217188
}
218189
}

app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ class ErrorUtil {
156156
// fallback to showing a notification if no root view is available
157157
createNotification(context, errorInfo)
158158
} else {
159-
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
159+
Snackbar.make(rootView, errorInfo.messageStringId, Snackbar.LENGTH_LONG)
160160
.setActionTextColor(Color.YELLOW)
161161
.setAction(context.getString(R.string.error_snackbar_action).uppercase()) {
162162
openActivity(context, errorInfo)

app/src/main/java/org/schabi/newpipe/error/UserAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public enum UserAction {
3333
SHARE_TO_NEWPIPE("share to newpipe"),
3434
CHECK_FOR_NEW_APP_VERSION("check for new app version"),
3535
OPEN_INFO_ITEM_DIALOG("open info item dialog"),
36-
GETTING_MAIN_SCREEN_TAB("getting main screen tab");
36+
GETTING_MAIN_SCREEN_TAB("getting main screen tab"),
37+
PLAY_ON_POPUP("play on popup");
3738

3839
private final String message;
3940

app/src/main/java/org/schabi/newpipe/util/text/InternalUrlsHandler.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package org.schabi.newpipe.util.text;
22

33
import android.content.Context;
4-
import android.util.Log;
54

65
import androidx.annotation.NonNull;
7-
import androidx.appcompat.app.AlertDialog;
86

97
import org.schabi.newpipe.MainActivity;
10-
import org.schabi.newpipe.R;
11-
import org.schabi.newpipe.error.ErrorPanelHelper;
8+
import org.schabi.newpipe.error.ErrorInfo;
9+
import org.schabi.newpipe.error.ErrorUtil;
10+
import org.schabi.newpipe.error.UserAction;
1211
import org.schabi.newpipe.extractor.NewPipe;
1312
import org.schabi.newpipe.extractor.StreamingService;
1413
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
@@ -158,19 +157,13 @@ public static boolean playOnPopup(final Context context,
158157
disposables.add(single.subscribeOn(Schedulers.io())
159158
.observeOn(AndroidSchedulers.mainThread())
160159
.subscribe(info -> {
161-
final PlayQueue playQueue =
162-
new SinglePlayQueue(info, seconds * 1000L);
160+
final PlayQueue playQueue = new SinglePlayQueue(info, seconds * 1000L);
163161
NavigationHelper.playOnPopupPlayer(context, playQueue, false);
164162
}, throwable -> {
165-
if (DEBUG) {
166-
Log.e(TAG, "Could not play on popup: " + url, throwable);
167-
}
168-
new AlertDialog.Builder(context)
169-
.setTitle(R.string.player_stream_failure)
170-
.setMessage(
171-
ErrorPanelHelper.Companion.getExceptionDescription(throwable))
172-
.setPositiveButton(R.string.ok, null)
173-
.show();
163+
final var errorInfo = new ErrorInfo(throwable, UserAction.PLAY_ON_POPUP, url);
164+
// This will only show a snackbar if the passed context has a root view:
165+
// otherwise it will resort to showing a notification, so we are safe here.
166+
ErrorUtil.showSnackbar(context, errorInfo);
174167
}));
175168
return true;
176169
}

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,4 +877,6 @@
877877
<string name="trending_movies">Trending movies and shows</string>
878878
<string name="trending_music">Trending music</string>
879879
<string name="entry_deleted">Entry deleted</string>
880+
<string name="youtube_sign_in_confirm_not_bot_error">YouTube refused to provide data, asking for a login.\n\nYour IP might have been temporarily banned by YouTube, you can wait some time or switch to a different IP (for example by turning on/off a VPN, or by switching from WiFi to mobile data).</string>
881+
<string name="unsupported_content_in_country">This content is not available for the currently selected content country.\n\nChange your selection from \"Settings > Content > Default content country\".</string>
880882
</resources>

0 commit comments

Comments
 (0)