Add AccountTerminatedException for better error handling of terminated channels

This commit is contained in:
TobiGr 2021-03-22 10:35:05 +01:00
parent 284362fc15
commit bb3861ddce
5 changed files with 73 additions and 4 deletions

View File

@ -0,0 +1,31 @@
package org.schabi.newpipe.extractor.exceptions;
public class AccountTerminatedException extends ContentNotAvailableException {
private Reason reason = Reason.UNKNOWN;
public AccountTerminatedException(final String message) {
super(message);
}
public AccountTerminatedException(final String message, final Reason reason) {
super(message);
this.reason = reason;
}
public AccountTerminatedException(final String message, final Throwable cause) {
super(message, cause);
}
/**
* The reason for the violation. There should also be more info in the exception's message.
*/
public Reason getReason() {
return reason;
}
public enum Reason {
UNKNOWN,
VIOLATION
}
}

View File

@ -10,10 +10,7 @@ import com.grack.nanojson.JsonWriter;
import org.schabi.newpipe.extractor.MetaInfo;
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.exceptions.*;
import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.utils.JsonUtils;
@ -762,6 +759,16 @@ public class YoutubeParsingHelper {
final String alertText = getTextFromObject(alertRenderer.getObject("text"));
final String alertType = alertRenderer.getString("type", EMPTY_STRING);
if (alertType.equalsIgnoreCase("ERROR")) {
if (alertText != null && alertText.contains("This account has been terminated")) {
if (alertText.contains("violation") || alertText.contains("violating")) {
// possible error messages:
// "This account has been terminated for violating YouTube's Community Guidelines."
// "This account has been terminated for a violation of YouTube's Terms of Service."
throw new AccountTerminatedException(alertText, AccountTerminatedException.Reason.VIOLATION);
} else {
throw new AccountTerminatedException(alertText);
}
}
throw new ContentNotAvailableException("Got error: \"" + alertText + "\"");
}
}

View File

@ -9,6 +9,7 @@ import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.feed.FeedExtractor;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
@ -33,6 +34,9 @@ public class YoutubeFeedExtractor extends FeedExtractor {
final String feedUrl = YoutubeParsingHelper.getFeedUrlFrom(channelIdOrUser);
final Response response = downloader.get(feedUrl);
if (response.responseCode() == 404) {
throw new ContentNotAvailableException("Could not get feed: 404 - not found");
}
document = Jsoup.parse(response.responseBody());
}

View File

@ -6,6 +6,7 @@ import org.schabi.newpipe.downloader.DownloaderFactory;
import org.schabi.newpipe.downloader.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
@ -50,6 +51,13 @@ public class YoutubeChannelExtractorTest {
YouTube.getChannelExtractor("https://www.youtube.com/channel/DOESNT-EXIST");
extractor.fetchPage();
}
@Test(expected = AccountTerminatedException.class)
public void accountTerminatedFetch() throws Exception {
final ChannelExtractor extractor =
YouTube.getChannelExtractor("https://www.youtube.com/channel/UC0AuOxCr9TZ0TtEgL1zpIgA");
extractor.fetchPage();
}
}
public static class NotSupported {

View File

@ -4,10 +4,13 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.downloader.DownloaderFactory;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeFeedExtractor;
import java.io.IOException;
import java.util.Random;
import static org.junit.Assert.assertEquals;
@ -77,4 +80,20 @@ public class YoutubeFeedExtractorTest {
assertNoMoreItems(extractor);
}
}
public static class NotAvailable {
@BeforeClass
public static void setUp() throws IOException {
NewPipe.init(new DownloaderFactory().getDownloader(RESOURCE_PATH + "notAvailable/"));
}
@Test(expected = ContentNotAvailableException.class)
public void AccountTerminatedFetch() throws Exception {
YoutubeFeedExtractor extractor = (YoutubeFeedExtractor) YouTube
.getFeedExtractor("https://www.youtube.com/channel/UCTGjY2I-ZUGnwVoWAGRd7XQ");
extractor.fetchPage();
}
}
}