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
The pieces
|
Step |
Method |
What it does |
Applies to |
|---|---|---|---|
|
optional |
Cancels the open multipart session on the storage side, freeing any chunks already registered into it via |
Multipart path only |
|
|
optional |
Deletes the standalone temporary chunk objects your code PUT directly to storage before registering them. These are untouched by |
Multipart path only |
|
|
required, last |
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);
}
}