Skip to content

Conversation

@oguzkocer
Copy link
Contributor

This PR fixes several issues in the Kotlin WpRequestExecutor implementation:

  1. Multi-file upload progress reporting - Progress now correctly tracks cumulative upload across all files instead of resetting per file
  2. Missing exception handling - Upload errors are now properly caught and wrapped in RequestExecutionException
  3. Missing User-Agent header - Uploads now include proper client identification
  4. Resource leak - SSL certificate inspection now properly closes connections
  5. User-Agent override prevention - User-Agent header can no longer be overridden by request headers
  6. Code quality improvements - Refactored upload() method to reduce complexity and fix detekt warnings
  7. Eliminate code duplication - Extracted common logic between execute() and upload() methods

@oguzkocer oguzkocer added this to the 0.2 milestone Oct 25, 2025
Base automatically changed from multipart-upload to trunk October 27, 2025 20:26
@oguzkocer oguzkocer force-pushed the fix/kotlin-upload-progress-and-error-handling branch from be9e1e2 to 864b5a6 Compare October 27, 2025 20:33
Add test to verify that upload progress callbacks are invoked correctly
and that progress values are monotonically increasing. While this test
uses the /media endpoint which only supports single file uploads, it
validates the basic progress reporting behavior and documents expected
behavior for future multi-file upload scenarios.
Wrap the entire multipart body with ProgressRequestBody instead of
wrapping individual files. This ensures progress is cumulative across
all files rather than resetting for each file.

Before: With multiple files, progress would reset to 0% for each file
After: Progress smoothly increases from 0% to 100% across all files

Changes:
- Remove getRequestBody() helper method
- Build complete multipart body first
- Wrap entire body with ProgressRequestBody for cumulative tracking
Add try-catch blocks to handle network exceptions (SSL errors, unknown
host, no route to host) in the upload() method, matching the exception
handling pattern used in execute(). Without this, upload errors would
throw unhandled exceptions instead of being properly wrapped in
RequestExecutionException.
Add User-Agent header to upload requests to match the behavior of the
execute() method. This ensures uploads are properly identified with the
client version information.
Ensure HttpsURLConnection is properly closed after certificate
inspection to prevent resource leaks. Wrap the certificate extraction
in try-finally block to guarantee cleanup, and add exception handling
to gracefully handle cases where certificate inspection fails.
Use header() instead of addHeader() when setting User-Agent to ensure
it cannot be overridden by headers from the request. The header() method
replaces any existing header with the same name, while addHeader() would
append and potentially allow unwanted values.
Refactor upload() method to reduce complexity and length by extracting
helper methods:
- buildMultipartBody(): Builds the multipart form body
- wrapWithProgressTracking(): Wraps body with progress tracking
- buildUploadRequest(): Constructs the HTTP request
- executeUpload(): Executes the upload and returns response

Also fix detekt warnings:
- Remove unused RequestBody import
- Remove extra blank line
- Add suppression annotations for SSL error handler with detailed
  justification comments

This reduces the upload() method from 67 lines to 17 lines and
improves maintainability.
Consolidate duplicate code between execute() and upload() methods by
extracting shared functionality into helper methods:

- addRequestHeaders(): Handles adding custom headers and User-Agent for
  both request types, ensuring consistent header handling
- executeRequestSafely(): Centralizes exception handling, call execution,
  and response building with optional upload listener notification

This eliminates code duplication and ensures both methods handle errors,
headers, and responses identically. The upload listener is now correctly
notified with the actual Call object that gets executed.

Changes:
- Removed buildUploadRequest() and executeUpload() helper methods
- Both execute() and upload() now use common helpers
- Reduced overall code size and improved maintainability
- Added @Suppress("ThrowsCount") for exception handling (3 specific
  network exceptions need to be caught and converted)
@oguzkocer oguzkocer force-pushed the fix/kotlin-upload-progress-and-error-handling branch from 864b5a6 to 24dc0ea Compare October 27, 2025 20:38
@oguzkocer oguzkocer marked this pull request as ready for review October 27, 2025 22:01
@oguzkocer oguzkocer enabled auto-merge (squash) October 27, 2025 22:01
Copy link
Contributor

@adalpari adalpari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I've tested it on the Android app, and both uploading and progress seem to be working as expected.

Image Image Image Image

@oguzkocer oguzkocer merged commit 5998985 into trunk Oct 28, 2025
22 checks passed
@oguzkocer oguzkocer deleted the fix/kotlin-upload-progress-and-error-handling branch October 28, 2025 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants