wordpress-mobile / wordpress-mobile/GutenbergKit

iOS: bound stream writer threads silently swallow errors

Open
#438 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
29
Forks
6
Avg merge
1d 9h
Merged PRs (30d)
41

Description

Summary

The background writer threads used for bound stream pairs silently swallow all errors. If a FileHandle.read() fails mid-stream or OutputStream.write() returns an error, the thread exits without logging or propagating the failure. The output stream closes, the input stream sees EOF, and URLSession receives fewer bytes than Content-Length promised — resulting in a network error with no indication of the root cause.

Locations

On trunk:

  • RequestBody.makePipedFileSliceStreamios/Sources/GutenbergKitHTTP/RequestBody.swift (~line 217)

On feat/leverage-host-media-processing (PR #419):

  • DefaultMediaUploader.multipartBodyStreamios/Sources/GutenbergKit/Sources/Media/MediaUploadServer.swift (same pattern, copied from above)

The pattern

Thread.detachNewThread {
    defer {
        output.close()
        try? fileHandle.close()
    }

    var remaining = length
    while remaining > 0 {
        let chunkSize = min(65_536, remaining)
        // FileHandle.read error silently swallowed by try?
        guard let chunk = try? fileHandle.read(upToCount: chunkSize),
              !chunk.isEmpty else {
            break  // silent exit — no logging
        }
        // write error — silent exit
        guard Self.writeAll(chunk, to: output) else { return }
        remaining -= chunk.count
    }
}

Problems

  1. No logging: When the writer thread fails, there is no log message indicating what went wrong (I/O error, stream closed, etc.), making production issues hard to diagnose.
  2. No error propagation: The caller has no way to distinguish "stream completed successfully" from "stream failed after 50% of the file." Both look like the output stream closing.
  3. Root cause masked: URLSession will report a generic network/content-length mismatch error, hiding the actual cause (disk I/O failure, file deleted, permissions changed, etc.).

Suggested improvements

  • Log errors from FileHandle.read() and OutputStream.write() before exiting
  • Consider using os.Logger consistent with other upload server logging
  • Optionally, track whether the writer completed successfully so callers can report a more specific error

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with RequestBody.makePipedFileSliceStream in ios/Sources/GutenbergKitHTTP/RequestBody.swift and compare the copied pattern in MediaUploadServer.swift on feat/leverage-host-media-processing. Trace the FileHandle.read and OutputStream.write failure paths, then review existing upload-server logging for the appropriate os.Logger usage. Done means failures are logged and the stream outcome can distinguish successful completion from a failed write or read.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.