Skip to content

Commit 9db08d3

Browse files
committed
PR comments
1 parent 1eb98b7 commit 9db08d3

File tree

5 files changed

+85
-11
lines changed

5 files changed

+85
-11
lines changed
Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,43 @@
11
package dev.lavalink.youtube;
22

33
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
4+
import org.jetbrains.annotations.NotNull;
45

6+
import java.io.PrintWriter;
7+
import java.io.StringWriter;
58
import java.util.List;
69

710
/**
811
* Thrown when all clients failed to load a track.
912
*/
1013
public class AllClientsFailedException extends FriendlyException {
14+
private final List<ClientException> clientExceptions;
15+
1116
/**
1217
* @param suppressed The exceptions that were caused client failures.
1318
*/
14-
public AllClientsFailedException(List<Throwable> suppressed) {
15-
super("All clients failed to load the item. See suppressed exceptions for details.", Severity.SUSPICIOUS, null);
16-
suppressed.forEach(this::addSuppressed);
19+
public AllClientsFailedException(@NotNull List<ClientException> suppressed) {
20+
super(createMessage(suppressed), Severity.SUSPICIOUS, null);
21+
this.clientExceptions = suppressed;
22+
}
23+
24+
@NotNull
25+
public List<ClientException> getClientExceptions() {
26+
return clientExceptions;
27+
}
28+
29+
private static String createMessage(@NotNull List<ClientException> exceptions) {
30+
StringWriter writer = new StringWriter();
31+
PrintWriter printer = new PrintWriter(writer);
32+
33+
printer.format("(yts.version: %s) All clients failed to load the item.", YoutubeSource.VERSION);
34+
35+
for (ClientException exception : exceptions) {
36+
printer.println();
37+
printer.println();
38+
printer.print(exception.getFormattedMessage());
39+
}
40+
41+
return writer.toString();
1742
}
1843
}

common/src/main/java/dev/lavalink/youtube/ClientException.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,41 @@
33
import dev.lavalink.youtube.clients.skeleton.Client;
44
import org.jetbrains.annotations.NotNull;
55

6+
import java.io.PrintWriter;
7+
import java.io.StringWriter;
8+
69
/**
710
* Wraps an exception with client context
811
*/
9-
public class ClientException extends Exception {
12+
public class ClientException extends RuntimeException {
13+
private final Client client;
14+
1015
public ClientException(@NotNull String message, @NotNull Client client, @NotNull Throwable cause) {
1116
super(String.format("Client [%s] failed: %s", client.getIdentifier(), message), cause);
12-
addSuppressed(ClientInformation.create(client));
17+
this.client = client;
18+
}
19+
20+
@NotNull
21+
public Client getClient() {
22+
return client;
23+
}
24+
25+
@NotNull
26+
public String getFormattedMessage() {
27+
StringWriter writer = new StringWriter();
28+
try (PrintWriter printer = new PrintWriter(writer)) {
29+
printer.print(getMessage());
30+
31+
Throwable cause = getCause();
32+
if (cause != null) {
33+
StackTraceElement[] stackTrace = cause.getStackTrace();
34+
int limit = Math.min(4, stackTrace.length);
35+
for (int i = 0; i < limit; i++) {
36+
printer.println();
37+
printer.format("\tat %s", stackTrace[i]);
38+
}
39+
}
40+
}
41+
return writer.toString();
1342
}
1443
}

common/src/main/java/dev/lavalink/youtube/ClientInformation.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ private ClientInformation(String message) {
1010

1111
public static ClientInformation create(Client client) {
1212
DetailMessageBuilder builder = new DetailMessageBuilder();
13-
builder.appendField("yts.version", YoutubeSource.VERSION);
1413
builder.appendField("client.identifier", client.getIdentifier());
1514
builder.appendField("client.options", client.getOptions());
1615
return new ClientInformation(builder.toString());

common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.List;
4040
import java.util.regex.Matcher;
4141
import java.util.regex.Pattern;
42+
import java.util.stream.Collectors;
4243

4344
import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS;
4445

@@ -215,7 +216,7 @@ public AudioItem loadItem(@NotNull AudioPlayerManager manager, @NotNull AudioRef
215216
@Nullable
216217
protected AudioItem loadItemOnce(@NotNull AudioReference reference) {
217218
AudioItem item = null;
218-
List<Throwable> exceptions = new ArrayList<>();
219+
List<ClientException> exceptions = new ArrayList<>();
219220

220221
try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) {
221222
Router router = getRouter(httpInterface, reference.identifier);
@@ -261,8 +262,14 @@ protected AudioItem loadItemOnce(@NotNull AudioReference reference) {
261262
throw ExceptionTools.toRuntimeException(e);
262263
}
263264

264-
if (item == null && !exceptions.isEmpty()) {
265-
throw new AllClientsFailedException(exceptions);
265+
if (!exceptions.isEmpty()) {
266+
if (item == null) {
267+
throw new AllClientsFailedException(exceptions);
268+
}
269+
270+
String exceptionSummary = exceptions.stream().map(ClientException::getFormattedMessage).collect(Collectors.toList()).toString();
271+
272+
log.debug("Exceptions suppressed whilst loading {}: {}", reference.identifier, exceptionSummary);
266273
}
267274

268275
return item;

common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void process(LocalAudioTrackExecutor localExecutor) throws Exception {
8686
log.debug("Failed to parse token from userData", e);
8787
}
8888

89-
List<Throwable> exceptions = new ArrayList<>();
89+
List<ClientException> exceptions = new ArrayList<>();
9090

9191
for (Client client : clients) {
9292
if (!client.supportsFormatLoading()) {
@@ -101,12 +101,26 @@ public void process(LocalAudioTrackExecutor localExecutor) throws Exception {
101101
} catch (CannotBeLoaded e) {
102102
throw e;
103103
} catch (Exception e) {
104+
if (e instanceof ScriptExtractionException) {
105+
// If we're still early in playback, we can try another client
106+
if (localExecutor.getPosition() >= BAD_STREAM_POSITION_THRESHOLD_MS) {
107+
throw e;
108+
}
109+
} else if ("Not success status code: 403".equals(e.getMessage()) ||
110+
"Invalid status code for player api response: 400".equals(e.getMessage())) {
111+
// As long as the executor position has not surpassed the threshold for which
112+
// a stream is considered unrecoverable, we can try to renew the playback URL with
113+
// another client.
114+
if (localExecutor.getPosition() >= BAD_STREAM_POSITION_THRESHOLD_MS) {
115+
throw e;
116+
}
117+
}
104118
exceptions.add(new ClientException(e.getMessage(), client, e));
105119
}
106120
}
107121

108122
if (!exceptions.isEmpty()) {
109-
throw ExceptionTools.wrapUnfriendlyExceptions("All clients failed to load the track.", Severity.SUSPICIOUS, new AllClientsFailedException(exceptions));
123+
throw new AllClientsFailedException(exceptions);
110124
}
111125
} catch (CannotBeLoaded e) {
112126
throw ExceptionTools.wrapUnfriendlyExceptions("This video is unavailable", Severity.SUSPICIOUS, e.getCause());

0 commit comments

Comments
 (0)