Gitlab Community Edition Instance

Commit 1e5438b2 authored by mhellka's avatar mhellka
Browse files

Improve error reporting for failed TUS uploads.

parent 3d386767
Pipeline #297373 passed with stages
in 9 minutes and 55 seconds
package de.gwdg.cdstar.rest.ext.tus;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
......@@ -10,6 +9,7 @@ import java.util.function.BiConsumer;
import de.gwdg.cdstar.Utils;
import de.gwdg.cdstar.rest.v3.async.UrlFetchService;
import de.gwdg.cdstar.web.common.model.ErrorResponse;
/**
* An {@link UrlFetchService} to allow other components (e.g. the archive update
......@@ -31,16 +31,18 @@ public class TusUrlFetch implements UrlFetchService {
}
@Override
public FetchHandle resolve(URI uri) throws IOException {
public FetchHandle resolve(URI uri) {
var upload = tus.getUpload(uri.getSchemeSpecificPart())
.orElseThrow(() -> new IOException("TUS Upload not found"));
var tusId = uri.getSchemeSpecificPart();
var upload = tus.getUpload(tusId)
.orElseThrow(() -> new ErrorResponse(400, "TusNotFound", "Unknown or expired TUS file id")
.detail("id", tusId));
if (!upload.tryLock())
throw new IOException("TUS upload locked");
throw new ErrorResponse(409, "TusLocked", "TUS file is locked, try again later");
if (!upload.isComplete())
throw new IOException("TUS upload not completed");
throw new ErrorResponse(409, "TusIncomplete", "TUS file is incomplete");
return new FetchHandle() {
private AsynchronousFileChannel readChannel;
......
......@@ -383,13 +383,7 @@ public class ArchiveUpdater {
.findFirst()
.orElseThrow(() -> ApiErrors.notImplemented("Fetch handler not found for the given URI."));
FetchHandle fetch;
try {
fetch = fetchHandler.resolve(uri);
} catch (Exception e) {
throw new ErrorResponse(500, "FetchFailed", "Fetch operation failed.")
.detail("error", e.getMessage());
}
FetchHandle fetch = fetchHandler.resolve(uri); // May throw ErrorResponse
CDStarFile target;
WritableByteChannel writeChannel;
......
package de.gwdg.cdstar.rest.v3.async;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.function.BiConsumer;
import de.gwdg.cdstar.web.common.model.ErrorResponse;
public interface UrlFetchService {
boolean canHandle(URI uri);
FetchHandle resolve(URI uri) throws IOException;
FetchHandle resolve(URI uri) throws ErrorResponse;
interface FetchHandle extends AutoCloseable {
long size();
......
......@@ -32,6 +32,7 @@ import de.gwdg.cdstar.runtime.CDStarRuntime;
import de.gwdg.cdstar.runtime.lts.LTSConfig;
import de.gwdg.cdstar.runtime.lts.bagit.BagitTarget;
import de.gwdg.cdstar.runtime.profiles.ProfileRegistry;
import de.gwdg.cdstar.web.common.model.ErrorResponse;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.Form;
import jakarta.ws.rs.core.MediaType;
......@@ -58,7 +59,12 @@ public class ArchiveUpdateTest extends BaseRestTest {
@Override
public FetchHandle resolve(URI uri) {
ByteBuffer data = ByteBuffer.wrap(Utils.base64decode(uri.getSchemeSpecificPart()));
ByteBuffer data;
try {
data = ByteBuffer.wrap(Utils.base64decode(uri.getSchemeSpecificPart()));
} catch (IllegalArgumentException e) {
throw new ErrorResponse(400, "TusNotFound", "This is not even a TUS id");
}
return new FetchHandle() {
@Override
......@@ -69,11 +75,11 @@ public class ArchiveUpdateTest extends BaseRestTest {
@Override
public void read(ByteBuffer dst, BiConsumer<Integer, Throwable> handler) {
var available = data.remaining();
if(available == 0)
if (available == 0)
handler.accept(-1, null);
else {
dst.put(data);
handler.accept(available- data.remaining(), null);
handler.accept(available - data.remaining(), null);
}
}
......@@ -109,7 +115,7 @@ public class ArchiveUpdateTest extends BaseRestTest {
private void file(String name, byte[] bytes, String filename, String contentType) {
formData.bodyPart(new StreamDataBodyPart("/" + name, new ByteArrayInputStream(bytes),
filename, MediaType.valueOf(contentType)));
filename, MediaType.valueOf(contentType)));
}
private void file(String name) {
......@@ -231,9 +237,9 @@ public class ArchiveUpdateTest extends BaseRestTest {
}
/**
* Test something repeatedly until it returns true. There is a short wait
* time between tests (defaults to 100th of maxTime) but other than that,
* this is a hot wait. Use with care.
* Test something repeatedly until it returns true. There is a short wait time
* between tests (defaults to 100th of maxTime) but other than that, this is a
* hot wait. Use with care.
*/
private void assertTrueEventually(BooleanSupplier test, long maxTime, TimeUnit unit) {
long now = System.currentTimeMillis();
......@@ -376,7 +382,7 @@ public class ArchiveUpdateTest extends BaseRestTest {
field("fetch:/target.txt", "base64:bad.input");
updateNoCheck(id);
assertError(500, "FetchFailed");
assertError(400, "TusNotFound");
}
@Test
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment