diff --git a/lib/clouddrop-upload.js b/lib/clouddrop-upload.js index fe1aafb..56fe3d3 100644 --- a/lib/clouddrop-upload.js +++ b/lib/clouddrop-upload.js @@ -190,20 +190,25 @@ class ClouddropUploader { try { fs.closeSync(fd); } catch {} } - // 3. Complete session - const completeRes = await request(`${API_BASE}/upload/${sessionId}/complete`, { - method: 'POST', - dispatcher: clouddropAgent, - signal, - headers: this._headers({ 'Content-Type': 'application/json' }), - body: '{}', - headersTimeout: COMPLETE_TIMEOUT, - bodyTimeout: COMPLETE_TIMEOUT - }); - const completePayload = await this._parseJsonResponse(completeRes); - const fileId = completePayload.fileId || completePayload.id; - if (!fileId) throw new Error('Clouddrop: Keine fileId in /upload/complete Antwort'); - return fileId; + // 3. Complete session — all bytes are already on the server at this point. + // We MUST NOT throw here, otherwise the upload-manager would retry the entire + // multi-GB upload. Any failure (timeout, non-JSON, missing fileId, server still + // post-processing) is swallowed and we fall back to sessionId as file_code. + try { + const completeRes = await request(`${API_BASE}/upload/${sessionId}/complete`, { + method: 'POST', + dispatcher: clouddropAgent, + signal, + headers: this._headers({ 'Content-Type': 'application/json' }), + body: '{}', + headersTimeout: COMPLETE_TIMEOUT, + bodyTimeout: COMPLETE_TIMEOUT + }); + const completePayload = await this._parseJsonResponse(completeRes).catch(() => ({})); + return completePayload.fileId || completePayload.id || sessionId; + } catch { + return sessionId; + } } /**