Improve error handling for playlist errors 403 and 404

This commit is contained in:
0xb00bface 2021-08-08 12:57:57 +02:00
parent fc5811e48e
commit 4946d0161a
2 changed files with 23 additions and 14 deletions

View File

@ -5,8 +5,10 @@
* Added Chaturbate configuration parameter to throttle requests to avoid * Added Chaturbate configuration parameter to throttle requests to avoid
429 errors. Be aware that this also slows down the online check for Chaturbate 429 errors. Be aware that this also slows down the online check for Chaturbate
models, especially, if you have a lot of models in your list. models, especially, if you have a lot of models in your list.
You have to play around a bit to find a value, which works for you.
* Fixed ConcurrentModificationException, which caused the recorded models tab * Fixed ConcurrentModificationException, which caused the recorded models tab
to turn blank to turn blank
* Fixed recordings not stopping, if playlist requests returned 403 or 404
4.4.3 4.4.3
======================== ========================

View File

@ -71,7 +71,7 @@ import okhttp3.Response;
public abstract class AbstractHlsDownload extends AbstractDownload { public abstract class AbstractHlsDownload extends AbstractDownload {
private static final transient Logger LOG = LoggerFactory.getLogger(AbstractHlsDownload.class); private static final transient Logger LOG = LoggerFactory.getLogger(AbstractHlsDownload.class);
private static final int TEN_SECONDS = 10_000; private static final int A_FEW_SECONDS = 10_000;
private transient NumberFormat nf = new DecimalFormat("000000"); private transient NumberFormat nf = new DecimalFormat("000000");
private transient int playlistEmptyCount = 0; private transient int playlistEmptyCount = 0;
@ -144,6 +144,10 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
} catch (Exception e) { } catch (Exception e) {
LOG.error("Couldn't download segment for model {}", model, e); LOG.error("Couldn't download segment for model {}", model, e);
stop(); stop();
} finally {
if (consecutivePlaylistErrors > 0) {
LOG.debug("Consecutive playlist errors: {}", consecutivePlaylistErrors);
}
} }
return this; return this;
} }
@ -163,17 +167,17 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
} }
protected void handleHttpException(HttpException e) throws IOException { protected void handleHttpException(HttpException e) throws IOException {
consecutivePlaylistErrors++;
if (e.getResponseCode() == 404) { if (e.getResponseCode() == 404) {
checkIfModelIsStillOnline("Playlist not found (404). Model {} probably went offline. Model state: {}"); checkIfModelIsStillOnline("Playlist not found (404). Model {} probably went offline. Model state: {}");
} else if (e.getResponseCode() == 403) { } else if (e.getResponseCode() == 403) {
checkIfModelIsStillOnline("Playlist access forbidden (403). Model {} probably went private or offline. Model state: {}"); checkIfModelIsStillOnline("Playlist access forbidden (403). Model {} probably went private or offline. Model state: {}");
}
if (consecutivePlaylistErrors >= 3) {
LOG.info("Playlist couldn't not be downloaded for model {} {} times. Stopping recording", model, consecutivePlaylistErrors, e);
stop();
} else { } else {
if (consecutivePlaylistErrors >= 3) { LOG.info("Playlist couldn't not be downloaded for model {} {} times: {}", model, consecutivePlaylistErrors, e.getLocalizedMessage());
LOG.info("Playlist couldn't not be downloaded for model {} {} times. Stopping recording", model, (consecutivePlaylistErrors + 1), e);
stop();
} else {
LOG.info("Playlist couldn't not be downloaded for model {} {} times: {}", model, (consecutivePlaylistErrors + 1), e.getLocalizedMessage());
}
} }
} }
@ -181,17 +185,21 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
ctbrec.Model.State modelState; ctbrec.Model.State modelState;
try { try {
modelState = model.getOnlineState(false); modelState = model.getOnlineState(false);
if (modelState == State.ONLINE) {
segmentPlaylistUrl = getSegmentPlaylistUrl(model);
waitSomeTime(TEN_SECONDS);
}
} catch (Exception e1) { } catch (Exception e1) {
modelState = State.UNKNOWN; modelState = State.UNKNOWN;
} }
LOG.info(errorMsg, model, modelState);
if (modelState != State.ONLINE) { if (modelState != State.ONLINE) {
stop(); stop();
return;
}
try {
LOG.debug("Trying to update playlist URL after waiting {}ms", A_FEW_SECONDS);
waitSomeTime(A_FEW_SECONDS);
segmentPlaylistUrl = getSegmentPlaylistUrl(model);
} catch (Exception e) {
LOG.error("Playlist URL couldn't be updated after waiting for {}ms", A_FEW_SECONDS, e);
} }
LOG.info(errorMsg, model, modelState);
} }
protected String getSegmentPlaylistUrl(Model model) throws IOException, ExecutionException, ParseException, PlaylistException, JAXBException { protected String getSegmentPlaylistUrl(Model model) throws IOException, ExecutionException, ParseException, PlaylistException, JAXBException {
@ -230,8 +238,7 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
Instant start = Instant.now(); Instant start = Instant.now();
recordingEvents.add(RecordingEvent.of("Playlist request")); recordingEvents.add(RecordingEvent.of("Playlist request"));
URL segmentsUrl = new URL(segmentPlaylistUrl); URL segmentsUrl = new URL(segmentPlaylistUrl);
Builder builder = new Request.Builder() Builder builder = new Request.Builder().url(segmentsUrl);
.url(segmentsUrl);
addHeaders(builder, Optional.ofNullable(model).map(Model::getHttpHeaderFactory).map(HttpHeaderFactory::createSegmentPlaylistHeaders).orElse(new HashMap<>()), model); addHeaders(builder, Optional.ofNullable(model).map(Model::getHttpHeaderFactory).map(HttpHeaderFactory::createSegmentPlaylistHeaders).orElse(new HashMap<>()), model);
Request request = builder.build(); Request request = builder.build();