Skip to content

Conversation

@jbermudezsonatype
Copy link

Enable HTTP servers to provide detailed error messages for failed package downloads via the X-Error-Message request header. This improves diagnostics when downloads fail on the server-side.

Benefits:

  • Server flexibility: Repository administrators can communicate specific failure reasons to R users
  • Better user experience: Actionable error messages instead of generic HTTP status codes (e.g., "Requested item is quarantined" vs "403")
  • Standards-compliant: Uses standard HTTP header mechanism

Implementation:
C-level changes (libcurl.c):

  • Added url_error_context struct to store per-URL error messages
  • Implemented rcvErrorHeader() callback to capture X-Error-Message header (case-insensitive, up to 512 chars)
  • Extended download_report_url_error() to include custom error messages in warnings when available
  • Added error context lifecycle management (allocation, cleanup) for concurrent downloads
  • Each concurrent download maintains an isolated error context via per-URL array indexing and CURLOPT_HEADERDATA

R-level changes (packages.R):

  • Enhanced download.packages() to capture C-level warnings using withCallingHandlers()

Testing:

  • Added backward compatibility tests to tests/download.file.R
  • Verified with servers sending X-Error-Message header
  • Tested concurrent downloads (install.packages with multiple packages)
  • Confirmed backward compatibility with servers not sending the header
  • Validated proper memory cleanup and per-URL context isolation

Technical details:

  • Header parsing handles case-insensitive matching per HTTP spec
  • Truncates messages exceeding 512 characters
  • Minimal performance impact: only allocates context when needed

…or package downloads

Enable HTTP servers to provide detailed error messages for failed
package downloads via the X-Error-Message request header. This
improves diagnostics when downloads fail on the server-side.

Benefits:
- Server flexibility: Repository administrators can communicate specific
 failure reasons to R users
- Better user experience: Actionable error messages instead of generic
 HTTP status codes (e.g., "Requested item is quarantined" vs "403")
- Standards-compliant: Uses standard HTTP header mechanism

Implementation:
C-level changes (libcurl.c):
- Added url_error_context struct to store per-URL error messages
- Implemented rcvErrorHeader() callback to capture X-Error-Message
 header (case-insensitive, up to 512 chars)
- Extended download_report_url_error() to include custom error messages
 in warnings when available
- Added error context lifecycle management (allocation, cleanup) for
 concurrent downloads
- Each concurrent download maintains isolated error context via
 per-URL array indexing and CURLOPT_HEADERDATA

R-level changes (packages.R):
- Enhanced download.packages() to capture C-level warnings using
 withCallingHandlers()

Safety fixes:
- Fixed stack check calculation: Added missing sizeof(double) for
 tstart array in R_CheckStack2 (pre-existing issue)

Testing:
- Added backward compatibility tests to tests/download.file.R
- Verified with servers sending X-Error-Message header
- Tested concurrent downloads (install.packages with multiple packages)
- Confirmed backward compatibility with servers not sending the header
- Validated proper memory cleanup and per-URL context isolation

Technical details:
- Header parsing handles case-insensitive matching per HTTP spec
- Truncates messages exceeding 512 characters
- Minimal performance impact: only allocates context when needed
@bbolker
Copy link

bbolker commented Dec 30, 2025

(I think you know this since you've posted to r-devel, but just in case ...)

Are you aware that this is a one-way mirror of the R code base, i.e. that pull requests here aren't noted by the R developers? The r-devel@r-project.org mailing list and the R bugzilla site (see https://www.r-project.org/bugs.html, search for "bugzilla") are the venues for contributions to R (also see discussion here about contributing)

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.

2 participants