Skip to content

Commit bb3861d

Browse files
committed
Add AccountTerminatedException for better error handling of terminated channels
1 parent 284362f commit bb3861d

5 files changed

Lines changed: 73 additions & 4 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.schabi.newpipe.extractor.exceptions;
2+
3+
public class AccountTerminatedException extends ContentNotAvailableException {
4+
5+
private Reason reason = Reason.UNKNOWN;
6+
7+
public AccountTerminatedException(final String message) {
8+
super(message);
9+
}
10+
11+
public AccountTerminatedException(final String message, final Reason reason) {
12+
super(message);
13+
this.reason = reason;
14+
}
15+
16+
public AccountTerminatedException(final String message, final Throwable cause) {
17+
super(message, cause);
18+
}
19+
20+
/**
21+
* The reason for the violation. There should also be more info in the exception's message.
22+
*/
23+
public Reason getReason() {
24+
return reason;
25+
}
26+
27+
public enum Reason {
28+
UNKNOWN,
29+
VIOLATION
30+
}
31+
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
import org.schabi.newpipe.extractor.MetaInfo;
1111
import org.schabi.newpipe.extractor.Page;
1212
import org.schabi.newpipe.extractor.downloader.Response;
13-
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
14-
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
15-
import org.schabi.newpipe.extractor.exceptions.ParsingException;
16-
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
13+
import org.schabi.newpipe.extractor.exceptions.*;
1714
import org.schabi.newpipe.extractor.localization.Localization;
1815
import org.schabi.newpipe.extractor.stream.Description;
1916
import org.schabi.newpipe.extractor.utils.JsonUtils;
@@ -762,6 +759,16 @@ public static void defaultAlertsCheck(final JsonObject initialData) throws Parsi
762759
final String alertText = getTextFromObject(alertRenderer.getObject("text"));
763760
final String alertType = alertRenderer.getString("type", EMPTY_STRING);
764761
if (alertType.equalsIgnoreCase("ERROR")) {
762+
if (alertText != null && alertText.contains("This account has been terminated")) {
763+
if (alertText.contains("violation") || alertText.contains("violating")) {
764+
// possible error messages:
765+
// "This account has been terminated for violating YouTube's Community Guidelines."
766+
// "This account has been terminated for a violation of YouTube's Terms of Service."
767+
throw new AccountTerminatedException(alertText, AccountTerminatedException.Reason.VIOLATION);
768+
} else {
769+
throw new AccountTerminatedException(alertText);
770+
}
771+
}
765772
throw new ContentNotAvailableException("Got error: \"" + alertText + "\"");
766773
}
767774
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeFeedExtractor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.schabi.newpipe.extractor.StreamingService;
1010
import org.schabi.newpipe.extractor.downloader.Downloader;
1111
import org.schabi.newpipe.extractor.downloader.Response;
12+
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
1213
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
1314
import org.schabi.newpipe.extractor.feed.FeedExtractor;
1415
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
@@ -33,6 +34,9 @@ public void onFetchPage(@Nonnull Downloader downloader) throws IOException, Extr
3334
final String feedUrl = YoutubeParsingHelper.getFeedUrlFrom(channelIdOrUser);
3435

3536
final Response response = downloader.get(feedUrl);
37+
if (response.responseCode() == 404) {
38+
throw new ContentNotAvailableException("Could not get feed: 404 - not found");
39+
}
3640
document = Jsoup.parse(response.responseBody());
3741
}
3842

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractorTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.schabi.newpipe.downloader.DownloaderTestImpl;
77
import org.schabi.newpipe.extractor.NewPipe;
88
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
9+
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
910
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
1011
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
1112
import org.schabi.newpipe.extractor.exceptions.ParsingException;
@@ -50,6 +51,13 @@ public void nonExistentFetch() throws Exception {
5051
YouTube.getChannelExtractor("https://www.youtube.com/channel/DOESNT-EXIST");
5152
extractor.fetchPage();
5253
}
54+
55+
@Test(expected = AccountTerminatedException.class)
56+
public void accountTerminatedFetch() throws Exception {
57+
final ChannelExtractor extractor =
58+
YouTube.getChannelExtractor("https://www.youtube.com/channel/UC0AuOxCr9TZ0TtEgL1zpIgA");
59+
extractor.fetchPage();
60+
}
5361
}
5462

5563
public static class NotSupported {

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeFeedExtractorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
import org.junit.Test;
55
import org.schabi.newpipe.downloader.DownloaderFactory;
66
import org.schabi.newpipe.extractor.NewPipe;
7+
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
8+
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
79
import org.schabi.newpipe.extractor.exceptions.ParsingException;
810
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
911
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeFeedExtractor;
1012

13+
import java.io.IOException;
1114
import java.util.Random;
1215

1316
import static org.junit.Assert.assertEquals;
@@ -77,4 +80,20 @@ public void testMoreRelatedItems() throws Exception {
7780
assertNoMoreItems(extractor);
7881
}
7982
}
83+
84+
public static class NotAvailable {
85+
86+
@BeforeClass
87+
public static void setUp() throws IOException {
88+
NewPipe.init(new DownloaderFactory().getDownloader(RESOURCE_PATH + "notAvailable/"));
89+
}
90+
91+
@Test(expected = ContentNotAvailableException.class)
92+
public void AccountTerminatedFetch() throws Exception {
93+
YoutubeFeedExtractor extractor = (YoutubeFeedExtractor) YouTube
94+
.getFeedExtractor("https://www.youtube.com/channel/UCTGjY2I-ZUGnwVoWAGRd7XQ");
95+
extractor.fetchPage();
96+
}
97+
98+
}
8099
}

0 commit comments

Comments
 (0)