Skip to content

Commit e861fdd

Browse files
authored
fabric: properly retry download when fabric installer is invalid (#620)
1 parent b8baecc commit e861fdd

File tree

1 file changed

+41
-32
lines changed

1 file changed

+41
-32
lines changed

src/main/java/me/itzg/helpers/fabric/FabricMetaClient.java

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package me.itzg.helpers.fabric;
22

3-
import java.io.BufferedReader;
43
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.nio.ByteBuffer;
56
import java.nio.file.Files;
67
import java.nio.file.Path;
78
import java.time.Duration;
@@ -16,6 +17,7 @@
1617
import me.itzg.helpers.http.FileDownloadStatusHandler;
1718
import me.itzg.helpers.http.SharedFetch;
1819
import me.itzg.helpers.http.UriBuilder;
20+
import org.apache.commons.codec.binary.Hex;
1921
import org.jetbrains.annotations.NotNull;
2022
import org.jetbrains.annotations.Nullable;
2123
import reactor.core.publisher.Mono;
@@ -155,52 +157,59 @@ public Mono<Path> downloadLauncher(
155157
.handleStatus(statusHandler)
156158
.assemble()
157159
.retryWhen(Retry.backoff(downloadRetryMaxAttempts, downloadRetryMinBackoff).filter(IOException.class::isInstance))
158-
.flatMap(path -> skipValidation ? Mono.just(path) : validateLauncherJar(path))
159-
.doOnError(InvalidContentException.class, e -> log.warn("Invalid launcher jar, will try again", e))
160+
.flatMap(path -> skipValidation ?
161+
Mono.just(path)
162+
: validateLauncherJar(path).subscribeOn(Schedulers.boundedElastic())
163+
)
164+
.doOnError(InvalidContentException.class, e ->
165+
log.warn("Invalid launcher jar, will try again: {}", e.getMessage())
166+
)
160167
.retryWhen(Retry.backoff(downloadRetryMaxAttempts, downloadRetryMinBackoff).filter(InvalidContentException.class::isInstance))
161168
.checkpoint("downloadLauncher");
162169
}
163170

164171
private Mono<Path> validateLauncherJar(Path path) {
165-
return Mono.fromCallable(() -> {
166-
log.debug("Validating Fabric launcher file {}", path);
172+
return Mono.create(sink -> {
173+
log.debug("Validating Fabric launcher file {}", path);
167174

168-
if (!path.toFile().isFile()) {
169-
throw new InvalidContentException("Downloaded launcher jar is not a file");
170-
}
171-
try {
172-
final Properties installProperties = IoStreams.readFileFromZip(path, "install.properties", in -> {
173-
Properties p = new Properties();
174-
p.load(in);
175-
return p;
176-
}
177-
);
178-
if (installProperties == null) {
179-
debugDownloadedContent(path);
180-
throw new InvalidContentException("Downloaded launcher jar does not contain an install.properties");
181-
}
182-
if (!installProperties.containsKey("game-version")) {
183-
debugDownloadedContent(path);
184-
throw new InvalidContentException("Downloaded launcher jar does not contain a valid install.properties");
175+
if (!path.toFile().isFile()) {
176+
sink.error(new InvalidContentException("Downloaded launcher jar is not a file"));
177+
}
178+
try {
179+
final Properties installProperties = IoStreams.readFileFromZip(path, "install.properties", in -> {
180+
Properties p = new Properties();
181+
p.load(in);
182+
return p;
185183
}
186-
} catch (IOException e) {
184+
);
185+
if (installProperties == null) {
187186
debugDownloadedContent(path);
188-
throw new InvalidContentException("Downloaded launcher jar could not be read as a jar/zip", e);
187+
sink.error(new InvalidContentException("Does not contain an install.properties"));
189188
}
189+
else if (!installProperties.containsKey("game-version")) {
190+
debugDownloadedContent(path);
191+
sink.error(new InvalidContentException("Does not contain a valid install.properties"));
192+
}
193+
} catch (IOException e) {
194+
debugDownloadedContent(path);
195+
sink.error(new InvalidContentException("Could not be read as a jar/zip", e));
196+
}
190197

191-
return path;
192-
})
193-
.subscribeOn(Schedulers.boundedElastic());
198+
sink.success(path);
199+
});
194200
}
195201

196202
private static void debugDownloadedContent(Path path) {
197203
if (log.isDebugEnabled()) {
198-
try (BufferedReader reader = Files.newBufferedReader(path)) {
199-
final char[] buf = new char[100];
200-
final int amount = reader.read(buf);
201-
log.debug("Downloaded launcher jar content starts with: {}", new String(buf, 0, amount));
204+
try (InputStream in = Files.newInputStream(path)) {
205+
final byte[] buf = new byte[100];
206+
final int amount = in.read(buf);
207+
208+
log.debug("Downloaded launcher jar content starts with: {}",
209+
Hex.encodeHexString(ByteBuffer.wrap(buf, 0, amount))
210+
);
202211
} catch (IOException e) {
203-
throw new GenericException("Failed to read downloaded launcher jar for debugging", e);
212+
log.warn("Failed to debug content of launcher jar", e);
204213
}
205214
}
206215
}

0 commit comments

Comments
 (0)