Skip to content

WIP: feat(transport): TUS upload for large attachments#1545

Draft
jpnurmi wants to merge 15 commits intojpnurmi/feat/http-retryfrom
jpnurmi/feat/tus
Draft

WIP: feat(transport): TUS upload for large attachments#1545
jpnurmi wants to merge 15 commits intojpnurmi/feat/http-retryfrom
jpnurmi/feat/tus

Conversation

@jpnurmi
Copy link
Collaborator

@jpnurmi jpnurmi commented Feb 27, 2026

  • Large attachments (>=100 MB) are stored as attachment-ref envelope items
  • Database layer stores large attachment files separately in db/attachments/<uuid>/
  • Transport layer streams each attachment-ref to the server via TUS before sending the envelope

See also:

#skip-changelog (wip)

@jpnurmi jpnurmi force-pushed the jpnurmi/feat/tus branch 2 times, most recently from da2ce2d to 0946169 Compare March 2, 2026 09:32
@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 2, 2026

@sentry review

@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 2, 2026

@cursor review

@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 2, 2026

@cursor review

@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 2, 2026

@cursor review

}
}
return 0;
}
Copy link

Choose a reason for hiding this comment

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

Debug function writes directly to stderr bypassing logging

Low Severity

The new debug_function added as a CURLOPT_DEBUGFUNCTION callback writes HTTP traffic details (headers, JSON bodies) directly to stderr via fprintf, bypassing the SDK's SENTRY_DEBUG/SENTRY_WARN logging infrastructure. Given the PR is titled "WIP", this appears to be development debugging code — it uses non-standard => / <= prefixes and selectively prints JSON-looking payloads, which is useful during development but inconsistent with the rest of the codebase.

Fix in Cursor Fix in Web

@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 3, 2026

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: copy_file_range fallback misses common filesystem errors
    • Expanded the copy_file_range fallback condition to also break on EXDEV, EOPNOTSUPP, and EINVAL so the read/write fallback handles these recoverable cases.

Create PR

Or push these changes by commenting:

@cursor push 76476611c4
Preview (76476611c4)
diff --git a/src/path/sentry_path_unix.c b/src/path/sentry_path_unix.c
--- a/src/path/sentry_path_unix.c
+++ b/src/path/sentry_path_unix.c
@@ -362,7 +362,8 @@
             goto done;
         } else if (errno == EAGAIN || errno == EINTR) {
             continue;
-        } else if (errno == ENOSYS) {
+        } else if (errno == ENOSYS || errno == EXDEV || errno == EOPNOTSUPP
+            || errno == EINVAL) {
             break;
         } else {
             rv = 1;
This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

@jpnurmi jpnurmi force-pushed the jpnurmi/feat/tus branch from a69528d to 44d6ecc Compare March 3, 2026 09:27
@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 3, 2026

@cursor review

@jpnurmi jpnurmi force-pushed the jpnurmi/feat/tus branch from 3bc1ee2 to 37004bf Compare March 5, 2026 08:03
@jpnurmi
Copy link
Collaborator Author

jpnurmi commented Mar 5, 2026

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@jpnurmi jpnurmi force-pushed the jpnurmi/feat/tus branch 3 times, most recently from eb0ead2 to 4ad89c0 Compare March 16, 2026 13:03
@jpnurmi jpnurmi force-pushed the jpnurmi/feat/http-retry branch from b133fd6 to 93db900 Compare March 17, 2026 16:15
jpnurmi and others added 7 commits March 19, 2026 17:00
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add body_path to prepared HTTP requests for streaming file uploads from
disk. Implement TUS protocol request formatting, upload URL construction,
response cleanup helper, Location header parsing, and curl debug logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache attachments >= 100 MB to disk at envelope preparation time, then
upload them via TUS protocol before sending the envelope. The envelope
carries lightweight attachment-ref items that point to the uploaded
location instead of embedding the full payload.

Key changes:
- Add attachment helpers (get_size, get_filename, type_to_string)
- Add envelope attachment-ref item type with location/content_type
- Cache large attachments to <db>/cache/<uuid>/ with refs.json metadata
- TUS upload with 404 fallback, retry integration, cache cleanup
- Skip large attachments in envelope serialization (size threshold)
- Fix envelope deserialization deadlock on bgworker thread

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hment()

Restore the helper that was dropped during the tus-separate refactor,
keeping the commented-out testing hook for small .dmp files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch from TUS "Creation With Upload" (single POST with body) to
TUS "Creation" (POST without body) + upload (PATCH with body).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jpnurmi and others added 6 commits March 19, 2026 17:00
This temporarily reverts commit 5a4097f1db4ae749370b0d82a2dc447ce5e8fc78
until it's supported on the server side.
The cache directory will contain actual attachment files alongside
this metadata file, so use a namespaced name to prevent collisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…od at transport time

Replace sentry__is_large_attachment(path, size) with
sentry__attachment_is_external(att) which returns true for MINIDUMP type
or size >= SENTRY_LARGE_ATTACHMENT_SIZE. Minidumps are always cached as
external files; other large attachments continue to be cached by size.

Rename sentry__cache_large_attachments to sentry__cache_external_attachments.

At transport time, resolve_and_send_external_attachments checks each
cached attachment: large files with TUS support go via TUS upload,
smaller files are inlined into the envelope. For raw envelopes (read
from disk on restart), sentry__envelope_append_raw_attachment builds
the item bytes and appends them directly to the raw payload buffer.

External attachment cleanup is deferred until after successful send
so files survive for retry on network failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pty POST

- Resolve relative Location header against DSN origin (sentry__dsn_resolve_url)
- Add x-sentry-auth header to TUS upload PATCH request
- Use CURLOPT_CUSTOMREQUEST for bodyless POST to avoid curl's default
  Content-Type: application/x-www-form-urlencoded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add append_raw_attachment_ref() to append attachment-ref items to raw
(serialized) envelopes by directly manipulating the payload buffer.
sentry__envelope_add_attachment_ref() dispatches to this for raw
envelopes, so callers don't need to know about the envelope format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jpnurmi and others added 2 commits March 19, 2026 17:32
Instead of sending attachment-refs in a separate envelope, append them
to the event envelope so the server can associate them in one request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show upload progress (MB uploaded, percentage, speed) via the progress
callback. Suppress per-chunk "=> Send" noise for non-JSON data since
the progress callback covers that. Keep recv logging for all responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant