Dear R-devel community, I would like to propose adding support for capturing and displaying custom error messages via the X-Error-Message HTTP response header when downloading packages (via install.packages() and download.file()).
Motivation: Currently, when package downloads fail due to server-side policies (security restrictions, policy violations, etc.), users only receive generic HTTP status codes like "403 Forbidden". Repository managers/administrators have no way to communicate specific failure reasons to R users, making troubleshooting difficult. Proposal: Capture the error message via "X-Error-Message" header (if present) from HTTP error responses and display them alongside standard error messages. Example output with the enhancement: Warning: cannot open URL 'https://...' HTTP status was '403 Forbidden' Error message: Requested item is quarantined by security policy Industry Context: This challenge is well-recognized across package management ecosystems, and major tools have implemented similar solutions: Custom error message headers (similar to this proposal): - NuGet (.NET): Uses custom headers for server-side warnings/errors https://github.com/NuGet/Home/wiki/%5BSpec%5D-Server-side-warnings-for-NuGet-client - Hugging Face (ML models): Implements structured error messages in HTTP headers https://huggingface.co/docs/huggingface_hub/en/package_reference/utilities#huggingface_hub.errors.HfHubHTTPError Structured error formats (RFC 9457 "Problem Details"): - Maven (Java): Recently added RFC 9457 support for detailed error reporting https://github.com/apache/maven-resolver/pull/1502 - uv (Python): Implementing RFC 9457 for enhanced diagnostics https://github.com/astral-sh/uv/pull/16199 Note: While RFC 9457 provides rich structured errors, a custom header approach (as used by NuGet/Hugging Face) offers similar user benefits with minimal implementation complexity and is more appropriate for R's architecture. Implementation: I have a working implementation that: C-level changes (src/modules/internet/libcurl.c): - Adds struct for per-URL error message storage - Implements callback function for case-insensitive header capture - Extends download_report_url_error() to include custom messages - Maintains isolated error contexts for concurrent downloads (thread-safe) R-level changes (src/library/utils/R/packages.R): - Uses withCallingHandlers() to capture C-level warnings - Preserves immediate warning display in interactive sessions Testing: - Added backward compatibility tests to tests/download.file.R - Verified with servers sending X-Error-Message headers - Tested concurrent downloads (install.packages with multiple packages) - Confirmed backward compatibility when the header is absent - Validated proper memory cleanup and error context isolation Technical details: - Header parsing: case-insensitive per HTTP spec - Message length: truncates at 512 characters - Performance: minimal overhead, context allocated only when needed - Standards compliant: uses standard HTTP header mechanism - Backward compatible: no behavior change when the header is absent I am happy to provide the complete patch and discuss implementation details. Would the R Core team and community be interested in this enhancement? -- Best regards, Julian Bermudez Valderrama, Software Engineer at Sonatype. ______________________________________________ [email protected] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
