S-Drive 3.6 Documentation

Canceling an Upload

This page walks through abandoning an upload that was started with initializeUpload but never finished — the client-side upload failed, the connection dropped, the user navigated away, or you've otherwise decided to stop rather than resume.

Each step links to its own reference page with full parameter details; this page is about how they fit together, plus a complete worked example for each path.

How to cancel an upload

Nothing about an abandoned upload cleans itself up automatically. A WIP Salesforce record stays in "in progress" state indefinitely unless you delete it, and on the multipart path, an open session and any chunks already sent to storage stick around independently unless something explicitly tells the storage service to let them go. Which calls you need depends on how far the upload got before it stalled.

Additional Documentation

https://cyangate.atlassian.net/wiki/x/LIFvt - used if needed for multipart upload

https://cyangate.atlassian.net/wiki/x/OIFvt - used if needed for multipart upload

https://cyangate.atlassian.net/wiki/x/HoFvt - always used to cancel any type of upload

The two paths

771c766b-cf5a-46df-927d-7cfb06762dca

The pieces

Step

Method

What it does

Applies to

optional

https://cyangate.atlassian.net/wiki/x/OIFvt

Cancels the open multipart session on the storage side, freeing any chunks already registered into it via copyPartMultiPartUpload. Silently does nothing if the session is already gone (completed or already aborted).

Multipart path only

optional

https://cyangate.atlassian.net/wiki/x/LIFvt

Deletes the standalone temporary chunk objects your code PUT directly to storage before registering them. These are untouched by abortMultiPartUpload. You supply the exact keys.

Multipart path only

required, last

https://cyangate.atlassian.net/wiki/x/HoFvt

Deletes the WIP Salesforce record, and by default whatever exists at the file's final storage key. Required on both paths — it's the only step the simple path needs.

Both paths

abortMultiPartUpload and deleteMultiParts are independent of each other — they touch different things (an open session vs. standalone objects), so there's no required order between them, and either can be skipped if it doesn't apply to your situation (e.g. no chunks were registered yet, or none were PUT yet). Doing both before cancelUpload is the recommended order, so the WIP record is the last thing removed once there's nothing left it needs to account for.

Full example: simple path

// initializeUpload created the WIP record; the direct upload to storage
// never completed (network failure, user cancelled, etc.)

List<ResultObject> results = SDriveTools.cancelUpload(
    new List<Id>{ info.wipFileId },
    caseId
);

for (ResultObject r : results) {
    if (r.status == 'fail') {
        System.debug(LoggingLevel.ERROR, 'Failed to cancel upload: ' + r.errorMessage);
    }
}

Full example: multipart path

// initializeUpload and initializeMultiPartUpload both succeeded; some
// chunks were PUT and registered, then the upload stalled and won't be resumed.

// STEP 1 — Cancel the open session (frees any chunks already registered into it)
try {
    SDriveTools.abortMultiPartUpload(info.fileLocation, uploadId);
} catch (SDriveException e) {
    System.debug(LoggingLevel.ERROR, 'Failed to abort multipart session: ' + e.getMessage());
}

// STEP 2 — Delete the standalone temp chunk objects that were PUT to storage.
// Reconstruct the keys — this method doesn't derive them for you.
List<String> tempKeys = new List<String>();
for (Integer partNumber = 1; partNumber <= chunksSentSoFar; partNumber++) {
    tempKeys.add(info.fileLocation + '.' + (partNumber - 1));
}

try {
    SDriveTools.deleteMultiParts(tempKeys);
} catch (SDriveException e) {
    System.debug(LoggingLevel.ERROR, 'Failed to delete temp chunk objects: ' + e.getMessage());
}

// STEP 3 — Same required last step as the simple path
List<ResultObject> results = SDriveTools.cancelUpload(
    new List<Id>{ info.wipFileId },
    caseId
);

for (ResultObject r : results) {
    if (r.status == 'fail') {
        System.debug(LoggingLevel.ERROR, 'Failed to cancel upload: ' + r.errorMessage);
    }
}