Repository navigation
fix(upload): never throw from abortUpload when the worker is stopped - #6825
ToteMeiSter wants to merge 3 commits into
Conversation
WorkManager calls ListenableWorker.stop() -> onStopped() from the invokeOnCancellation handler of its coroutine. abortUpload() sent a DAV DELETE there and let network/DAV errors (and NPEs on an uninitialised upload folder) escape, which surfaces as CompletionHandlerException and kills the process. Return early when nothing was started and log DavException/IOException instead of throwing. Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru> Assisted-by: Claude-Code:claude-opus-5-5
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to Abort now skips deletion when prerequisites are unavailable and contains expected deletion and callback failures, allowing cancellation cleanup to continue. No supported merge-blocking risk remains. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Cancellation now contains ordinary upload-abort failures so remaining cleanup can run. The account, deletion target, and credentials remain unchanged. Remote cleanup after a failed deletion remains best-effort, and server-side recovery guarantees have not been established. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.kt (1)
351-351: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value
onSuccess()exceptions can still escapeabortUpload.The KDoc says the function must never throw. The
onSuccess()lambda runs inside thedeletecallback, inside thetry. OnlyDavExceptionandIOExceptionare caught. ARuntimeExceptionfrom the callback propagates out ofabortUpload. The same applies to any other runtime exception fromDavResourceorokhttp. The current caller passes{}, so this is not triggered today. The "never throws" contract is still not fully enforced.Consider also catching
RuntimeException, with a detekt suppression forTooGenericExceptionCaught, asupload()already does withException.
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
08eb2246-d96f-49a7-b45c-5eae4e70c7ec
📒 Files selected for processing (2)
app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.ktapp/src/test/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploaderAbortTest.kt
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
abortUpload() runs from onStopped() inside a cancellation handler and must never throw. It caught only DavException and IOException, so a RuntimeException from the success callback, dav4jvm or OkHttp still escaped. Catch Exception, like upload() already does. Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru> Assisted-by: Claude-Code:claude-opus-5-5
|
Thanks @coderabbitai. Fixed the nitpick on |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
d93d5cd4-944f-400f-8eff-77352a56a5da
📒 Files selected for processing (2)
app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.ktapp/src/test/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploaderAbortTest.kt
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.
When the upload folder is already gone, abortUpload() calls onSuccess() from the NotFoundException handler, where the following catch does not apply. Guard that call too. Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru> Assisted-by: Claude-Code:claude-opus-5-5
|
Tip For best results, initiate chat on the files or code changes.
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! You are interacting with an AI system. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
This is a bug fix and all CodeRabbit review threads are resolved. Once it is approved and merged, would it be possible to backport it to Suggested command for a maintainer after merge: This comment was drafted with AI assistance (Claude Code). |
Problem
UploadAndShareFilesWorker.onStopped()callsChunkedFileUploader.abortUpload()synchronously. WorkManager runsonStopped()inside the cancellation handler of its coroutine (WorkerWrapper→ListenableWorker.stop()). An exception thrown there becomes aCompletionHandlerExceptionon aWM.task-Nthread and crashes the process.Follow-up to #5605 / #5607, which handled
NotFoundExceptiononly.abortUpload()can still throw:IOException: the DELETE is sent while the network is gone, which is the usual reason the work is stopped (screen off, Doze, airplane mode);HttpException/DavException: for example a 5xx response;NullPointerException: fromokHttpClientNoRedirects!!anduploadFolderUri.toHttpUrlOrNull()!!when the work is stopped before the chunked upload started.To reproduce: send a file larger than 1 MiB to a chat and switch the phone to airplane mode during the upload. The process can crash in
WM.task(this is how it showed up in a fork build after the phone woke from sleep).Fix
abortUpload()never throws:NotFoundExceptionstill callsonSuccess();DavExceptionandIOExceptionare logged;onSuccess()is not called.onStopped()and the worker logic are unchanged. Code change:ChunkedFileUploader.kt, +15/−4.Tests
New
ChunkedFileUploaderAbortTest(MockWebServer), 5 cases: called before the upload started, connection dropped, 500, 404, 204. On the old code 3 of them fail (NPE,IOException,HttpException500).testGplayDebugUnitTestpasses, ktlint is clean, detekt reports no new findings.Tested by the author on a Huawei DEL-LX9.
Note: #6770 moves the
abortUpload()call fromonStopped()into afinallyblock indoWork(). The fix still applies there: an exception from that block would fail the work.🏁 Checklist
/backport to stable-xx.x🤖 AI (if applicable)
The analysis, the fix and the test were prepared with an AI assistant (Claude Code). I reviewed the change and tested it on a device.
🤖 Generated with Claude Code