From 29dcac23cf239a166b93675430bcbb7c7b4c676e Mon Sep 17 00:00:00 2001 From: AsamK Date: Tue, 22 Sep 2026 21:04:34 +0200 Subject: [PATCH] Improve attachment download failure handling Fixes #2116 --- .../manager/helper/AttachmentHelper.java | 2 +- .../manager/storage/AttachmentStore.java | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java index 85ea14a4..82d8a9c4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java @@ -168,7 +168,7 @@ public class AttachmentHelper { try { attachmentStore.storeAttachment(pointer, outputStream -> this.retrieveAttachment(pointer, outputStream)); } catch (IOException e) { - logger.warn("Failed to download attachment ({}), ignoring: {}", pointer.getRemoteId(), e.getMessage()); + logger.warn("Failed to download attachment ({}), ignoring", pointer.getRemoteId(), e); } } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/AttachmentStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/AttachmentStore.java index 00a284dd..44ea22d4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/AttachmentStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/AttachmentStore.java @@ -8,9 +8,11 @@ import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemo import org.whispersystems.signalservice.api.util.StreamDetails; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.Optional; public class AttachmentStore { @@ -51,8 +53,23 @@ public class AttachmentStore { private void storeAttachment(final File attachmentFile, final AttachmentStorer storer) throws IOException { createAttachmentsDir(); - try (OutputStream output = new FileOutputStream(attachmentFile)) { - storer.store(output); + final var temporaryFile = Files.createTempFile(attachmentsPath.toPath(), + attachmentFile.getName() + ".", + ".tmp"); + try { + try (OutputStream output = Files.newOutputStream(temporaryFile)) { + storer.store(output); + } + try { + Files.move(temporaryFile, + attachmentFile.toPath(), + StandardCopyOption.ATOMIC_MOVE, + StandardCopyOption.REPLACE_EXISTING); + } catch (AtomicMoveNotSupportedException e) { + Files.move(temporaryFile, attachmentFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } finally { + Files.deleteIfExists(temporaryFile); } }