Restore HTTP.Exceptions as a deprecating compat shim + migration note - #1315
Merged
Merged
Conversation
Re-add HTTP.Exceptions as a thin deprecated submodule forwarding HTTPError, StatusError, ConnectError and TimeoutError to the canonical top-level names via Base.@deprecate_binding (as the existing escape -> escapeuri), so downstream `catch ... isa HTTP.Exceptions.StatusError` keeps working with a deprecation warning. RequestError, @Try and current_exceptions_to_string are not reinstated; the migration guide documents them (RequestError has no drop-in -- the underlying exception propagates and isrecoverable classifies it). Closes JuliaWeb#1314.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1315 +/- ##
==========================================
- Coverage 87.32% 87.17% -0.16%
==========================================
Files 29 29
Lines 11326 11326
==========================================
- Hits 9890 9873 -17
- Misses 1436 1453 +17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Contributor
Author
|
The |
krynju
added a commit
to krynju/AWS.jl
that referenced
this pull request
Jun 25, 2026
`_HTTP_V2 = !isdefined(HTTP, :Exceptions)` is no longer reliable: HTTP 2.x re-adds `HTTP.Exceptions` as a deprecating compat shim (JuliaWeb/HTTP.jl#1315), so on a 2.x release carrying that shim the flag would flip to `false` and AWS.jl would silently run its 1.x code paths on HTTP 2. Switch to `pkgversion(HTTP) >= 2` (with an `HTTP.EmptyBody` feature-detection fallback for Julia < 1.9 — a genuine 2.x-only type that is not shimmed back). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krynju
added a commit
to krynju/AWSS3.jl
that referenced
this pull request
Jun 25, 2026
The `isdir` test picked the `StatusError` constructor via `isdefined(AWS.HTTP, :Exceptions)`. HTTP 2.x re-adds `HTTP.Exceptions` as a deprecating compat shim (JuliaWeb/HTTP.jl#1315), so on such a release the test would take the 1.x branch and call the removed 4-arg `StatusError(status, method, target, response)` constructor → MethodError. Key off `HTTP.EmptyBody` (a genuine 2.x-only type that is not shimmed) instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krynju
added a commit
to JuliaComputing/GitForge.jl
that referenced
this pull request
Jun 25, 2026
`_HTTP_V2 = !isdefined(HTTP, :Header)` keys off a removed binding's absence, which is fragile: HTTP.jl 2.x has re-added other removed bindings as deprecating shims (e.g. HTTP.Exceptions, JuliaWeb/HTTP.jl#1315), so a future Header shim would silently flip the flag. Use `pkgversion(HTTP) >= 2`, falling back to a genuine 2.x-only type (`HTTP.EmptyBody`) when pkgversion is unavailable (Julia < 1.9). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nkottary
added a commit
to JuliaWeb/GitForge.jl
that referenced
this pull request
Jun 29, 2026
* Update HTTP.jl to 2.4.0
* Fix compatibility with HTTP.jl 2.x API
- Replace HTTP.Header[] with Pair{String,String}[]; the HTTP.Header
type alias was removed from the public API in HTTP.jl 2.0.
- Replace HTTP.StatusError(status, method, url, resp) with
HTTP.StatusError(resp); the v2 StatusError struct has only
(status, response) fields and no longer takes method/url arguments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix remaining HTTP.jl 2.x test failures
Replace HTTP.Header[] with Pair{String,String}[] since HTTP.Header was
removed in HTTP.jl 2.x. Drop the !isempty(out) verbose log assertion
since HTTP.jl 2.x prints verbose output directly to stdout rather than
through Julia's logging system, making it uncapturable by TestLogger.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Drop Julia 1.6 support
HTTP.jl 2.x requires Julia 1.7+, so Julia 1.6 can no longer resolve
the dependency. Remove 1.6 from the CI matrix and bump the julia compat
bound to 1.7 accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Remove docs/Manifest.toml from version control
Add it to .gitignore so it is generated fresh during CI via
Pkg.instantiate(), avoiding stale pinned dependencies (e.g. the
TimeZones build failure on current Julia).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add missing docstrings to docs
19 documented symbols were not referenced in the manual, causing
makedocs to error with :missing_docs. Add them across three areas:
- API endpoints: get_branches, delete_branch, create_repo (owner/repo
variant), subscribe/unsubscribe_from_pull_request, groups,
list_issues, list_pipeline_schedules, and all pull request comment
CRUD functions
- Bitbucket section: Bitbucket module, BitbucketAPI, RenderedPullRequestMarkup
- Internals: constructfield, write(::FieldContext, ...), @forge
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Bump version 0.4.4 -> 0.5.0
Dropping Julia 1.6 support and requiring HTTP.jl 2.x are both breaking
changes for existing users, warranting a minor version bump under
Julia's pre-1.0 conventions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add dual HTTP.jl 1.x/2.x support; bump version to 0.4.5
Widen HTTP compat from "2.4.0" to "1.10, 2" so the package resolves on
both HTTP 1.x and 2.x. The sole API incompatibility was the HTTP.StatusError
constructor (4-arg in 1.x, 1-arg in 2.x); this is guarded by a module-level
_HTTP_V2 constant derived from isdefined(HTTP, :Header) (works on Julia 1.6+).
Also fixes the pre-existing broken 2-arg HTTP.StatusError call in Bitbucket
pagination and replaces removed HTTP.status/HTTP.body accessor functions with
direct field access (compatible with both versions).
Restore Julia 1.6 to Project.toml compat and CI matrix: HTTP 1.x supports 1.6,
so users on 1.6 will resolve HTTP 1.x and the conditional paths handle the rest.
Version bump 0.5.0 → 0.4.5: dual-version support is additive, not breaking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* detect HTTP 2.x by package version, not HTTP.Header absence
`_HTTP_V2 = !isdefined(HTTP, :Header)` keys off a removed binding's absence,
which is fragile: HTTP.jl 2.x has re-added other removed bindings as deprecating
shims (e.g. HTTP.Exceptions, JuliaWeb/HTTP.jl#1315), so a future Header shim
would silently flip the flag. Use `pkgversion(HTTP) >= 2`, falling back to a
genuine 2.x-only type (`HTTP.EmptyBody`) when pkgversion is unavailable
(Julia < 1.9).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor: detect HTTP 2.x era via binding-owned VERSION
`HTTP.VERSION` only exists from HTTP.jl 2.0 on; under 1.x it resolves to the `VERSION` re-exported from `Base` (the Julia version). Guard with `Base.binding_module` before comparing, and bound to the 2.x line (`v"2" <= VERSION < v"3"`) so a future HTTP 3 isn't treated as 2.x. Replaces the prior version-detection.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix http compat
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: krynju <krystian.gulinski@juliahub.com>
tanmaykm
pushed a commit
to krynju/AWS.jl
that referenced
this pull request
Aug 7, 2026
* Support HTTP.jl 2.x alongside 1.x HTTP.jl 2.0 is a breaking release. Add a compatibility layer so AWS.jl works on both 1.x and 2.x, selected at load time via a feature flag. Client-side changes (src/utilities/http_compat.jl + call sites): - `StatusError` constructor changed from (status, method, target, response) to (status, response). - `RequestError`, `iserror`, `isbytes`, `resource`, and the `HTTP.Exceptions` submodule were removed; use `HTTP.isrecoverable` and local shims. - Response bodies are buffered as bytes (no `IOBuffer` bodies), header names are canonicalized, and connection timeouts surface as `TimeoutError` rather than `ConnectError`. Drop the GitHub.jl dependency: it pins HTTP < 2 and was used only by the API-generation tooling. Its three REST calls (authenticate/tree/blob) are reimplemented over HTTP + JSON. Tests updated to construct version-appropriate exceptions/bodies. The IMDS mock no longer replicates HTTP.jl's private retry internals (which differ across versions) and instead honors only the retry_check path IMDS relies on. Verified: unit suite passes under both HTTP 1.11 and HTTP 2.4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Restore GitHub.jl dependency for API generation Bring GitHub.jl back as a dependency and revert the API-generation tooling to use it (the hand-rolled GitHub REST shim from the HTTP 2 work is removed). This keeps all the HTTP.jl 1.x/2.x client compatibility from the parent branch while using GitHub.jl for `parse_aws_metadata`. Note: registered GitHub.jl (v5) still pins HTTP < 2, so with this dependency the resolver currently selects HTTP 1.x. Once GitHub.jl publishes a release with HTTP 1+2 support, HTTP 2 resolves without further changes (widen the `GitHub` compat bound if that support arrives in a new major version). Verified: unit suite passes (HTTP 1.11 + GitHub.jl). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Use a single HTTP-version flag across tests The test helpers gated their HTTP 1.x/2.x branches on an inline `isdefined(HTTP, :Exceptions)`, duplicating the detection that `AWS._HTTP_V2` already centralizes. Reference the package flag instead so version detection has a single source of truth. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * IMDS: treat HTTP.TimeoutError as a hop-limit (TTL) rejection on HTTP 2.x The IMDSv2 token PUT runs with `retry=false`; a hop-limit rejection manifests as a read timeout. On HTTP.jl 2.x that read-deadline timeout can surface as an `HTTP.TimeoutError` (the same way connection timeouts do — `is_connection_exception` already handles that), not only as a bare `ETIMEDOUT` `IOError`. Without this, `is_ttl_expired_exception` returns false, the IMDSv1 fallback is skipped, and the token fetch hard-fails in hop-limited (container) environments. Match `HTTP.TimeoutError` in the 2.x branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * http_compat: detect HTTP 2.x by version, not the Exceptions submodule `_HTTP_V2 = !isdefined(HTTP, :Exceptions)` is no longer reliable: HTTP 2.x re-adds `HTTP.Exceptions` as a deprecating compat shim (JuliaWeb/HTTP.jl#1315), so on a 2.x release carrying that shim the flag would flip to `false` and AWS.jl would silently run its 1.x code paths on HTTP 2. Switch to `pkgversion(HTTP) >= 2` (with an `HTTP.EmptyBody` feature-detection fallback for Julia < 1.9 — a genuine 2.x-only type that is not shimmed back). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: detect HTTP 2.x era via binding-owned VERSION `HTTP.VERSION` only exists from HTTP.jl 2.0 on; under 1.x it resolves to the `VERSION` re-exported from `Base` (the Julia version). Guard with `Base.binding_module` before comparing, and bound to the 2.x line (`v"2" <= VERSION < v"3"`) so a future HTTP 3 isn't treated as 2.x. Replaces the prior version-detection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CI: test against HTTP.jl 1.x and 2.x Add an `http` matrix axis that pins HTTP.jl to the selected major before running tests (the pin survives `Pkg.test`'s re-resolve), so both code paths are exercised. HTTP.jl 2 requires Julia >= 1.10, so the "min" Julia version is excluded from the HTTP 2 leg. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CI: pin HTTP before buildpkg, matching Onda.jl pattern Address review feedback (PR JuliaCloud#775): move the HTTP.jl pin ahead of `julia-buildpkg` so instantiation and precompilation happen once at the pinned version rather than resolving the latest and then downgrading, and pass the package UUID explicitly. Mirrors the multi-version-dependency CI approach used in Onda.jl that the reviewer referenced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix HTTP 2.x behavior regressions found in review Code review of the HTTP 1/2 compatibility layer surfaced several cases where the 2.x shims diverged from 1.x semantics: - IMDS: on 2.x every `TimeoutError` was classified as both a connection failure and a hop-limit rejection, with the connection check winning, making the IMDSv1 hop-limit fallback (issues JuliaCloud#654/JuliaCloud#649) unreachable. Discriminate on `TimeoutError.operation`: connect/tls_handshake phases are connection failures, read-phase timeouts are hop-limit rejections — the predicates are now disjoint. The same phase logic prevents `_is_connection_failure` from swallowing read timeouts from a reachable ECS credentials endpoint. - `_http_iserror` treated redirect statuses as errors, breaking the S3 wrong-region redirect re-sign flow on the Downloads backend. Mirror 1.x `HTTP.iserror` exactly. - HTTPBackend's retry check no longer retried transient timeouts on 2.x (`HTTP.isrecoverable` returns false for `TimeoutError`). Include connect-phase timeouts via `_is_connection_failure` and read-phase timeouts in `_is_recoverable_request_error`, matching 1.x's RequestError semantics. - On 2.x, `showerror` of a `StatusError` whose response has no request crashed in HTTP.jl, masking the real error. The `_statuserror` shim now attaches a minimal request when the response carries none. - The Downloads backend's synthetic response used `UInt8[]` as the body, which 1.x `HTTP.isbytes` classifies as inline, silently dropping `AWSException.streamed_body`. New `_streamed_body_placeholder()` shim restores the streamed marker per version, and tests now reuse it instead of duplicating the conditional. - Restore `HTTP.resource` semantics (e.g. empty path => "/") via a `_resource` shim instead of a hand-rolled target string. Unit suite passes on HTTP 1.11 (668) and HTTP 2.5.5 (672, including new phase-discrimination tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * IMDS: own the 401 token-refresh retry instead of delegating to HTTP.jl `IMDS.request` relied on the `retry_check`/`retry_delays` keywords to refresh an expired IMDSv2 token on a 401 and retry. HTTP.jl 2.x accepts those keywords for backwards compatibility but ignores them, so on 2.x the 401 propagated to the caller instead of transparently refreshing the token. Move the refresh-and-retry-once loop into `IMDS.request` itself and pass `retry=false`, giving identical single-attempt-per-call semantics on both HTTP.jl majors. The test mock previously reimplemented the retry keywords via `Base.retry`, which is exactly what masked this: it honored `retry_check` even though the real 2.x client does not. The mock now performs one attempt per call, like the real client, so the refresh retry is exercised through the actual code path — the existing request-count assertions pass unchanged. Unit suite passes on HTTP 1.11 (668) and HTTP 2.5.5 (672); the 2.x "retry_delays ... no longer supported" deprecation warning is gone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CI: skip the HTTP pin on the min Julia job The hard pin of HTTP to 1.11.0 made the `Pkg.develop(TestPkg)` in the test suite unresolvable on Julia 1.8: HTTP 1.11 needs ConcurrentUtilities >= 2.4, but with stdlibs fixed at v0.0.0 on Julia < 1.9 the Sockets compat caps ConcurrentUtilities at 2.2.1, and a pin cannot be moved by any resolve tier. Julia 1.8 can only resolve HTTP 1.x regardless (HTTP 2 requires Julia >= 1.10), so the pin adds no coverage on the min job — skip it there, matching the conditional pin pattern in Onda.jl's CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krynju
added a commit
to krynju/AWSS3.jl
that referenced
this pull request
Aug 10, 2026
* Add HTTP.jl 2.0 compat Bump HTTP compat to "1, 2". src/ only uses HTTP.header, whose signature is unchanged in 2.0. The one breaking usage is in tests: StatusError moved out of the Exceptions submodule and its constructor changed from (status, method, target, response) to (status, response). Construct it version-aware via isdefined(AWS.HTTP, :Exceptions). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: detect HTTP 2.x by EmptyBody, not the Exceptions submodule The `isdir` test picked the `StatusError` constructor via `isdefined(AWS.HTTP, :Exceptions)`. HTTP 2.x re-adds `HTTP.Exceptions` as a deprecating compat shim (JuliaWeb/HTTP.jl#1315), so on such a release the test would take the 1.x branch and call the removed 4-arg `StatusError(status, method, target, response)` constructor → MethodError. Key off `HTTP.EmptyBody` (a genuine 2.x-only type that is not shimmed) instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: detect HTTP 2.x era via binding-owned VERSION const `HTTP.VERSION` only exists from HTTP.jl 2.0 on; under 1.x it resolves to the `VERSION` re-exported from `Base` (the Julia version). Guard with `Base.binding_module` before comparing, and bound to the 2.x line (`v"2" <= VERSION < v"3"`) so a future HTTP 3 isn't treated as 2.x. Replaces the prior version-detection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: case-insensitive get_robust_case for HTTP.jl 2.x headers HTTP.jl 2.x canonicalizes response header names, so S3's `ETag` header arrives as `Etag`. get_robust_case only tried the lowercase (`etag`) and verbatim (`ETag`) spellings, so the canonicalized `Etag` missed both and threw `KeyError: key "ETag" not found` from s3_upload_part, breaking every multipart upload under HTTP.jl 2.x. Fall back to a full case-insensitive scan before throwing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: test against HTTP.jl 1.x and 2.x Add an `http` dimension to the CI matrix and pin HTTP.jl to the matrix major before instantiation, so both code paths are actually exercised. Without the pin the resolver selects HTTP 1.x, leaving the 2.x path untested. Fix two tests that only pass on HTTP 1.x: HTTP.jl 2.x canonicalizes response header names, so `s3_get_meta` returns `X-Amz-Meta-Foo`/`Etag` rather than the spellings S3 sends. Look those up via `get_robust_case`, and extend its unit test with a case that exercises the case-insensitive scan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * add * ci: drop archived actions-oidc-debugger step `github/actions-oidc-debugger` was archived in September 2025. Its Dockerfile pins `apk add go=$(cat .go-version)-r0`, which no longer resolves against Alpine 3.22's repos (musl has moved to -r12), so the image build fails and takes down every matrix job before Julia is installed. The step is purely diagnostic; role assumption via `aws-actions/configure-aws-credentials` is unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the deprecating
HTTP.Exceptionsshim and migration note discussed in #1314 (context and prevalence there).src/HTTP.jlre-addsHTTP.Exceptionsas a thin deprecated submodule forwarding the four relocated types to their top-level names:So
catch … isa HTTP.Exceptions.StatusErrorresolves again, forwarding toHTTP.StatusErrorwith a--depwarn=yeswarning — same mechanism as the existing@deprecate escape escapeuri, and like it, untested.RequestError,@try, andcurrent_exceptions_to_stringare not reinstated; the migration note covers them (RequestErrorhas no drop-in — the underlying exception propagates andisrecoverableclassifies it, #1310).docs/src/guides/migration-1x.mdgains an "Exceptions" section (Before/After forStatusErrorandRequestError) and a Final-Checklist line.Closes #1314.