Skip to content

fix(fetch): urgently correct broken request implementation#13

Merged
medz merged 5 commits intomainfrom
fix/request-constructor-signature
Mar 13, 2026
Merged

fix(fetch): urgently correct broken request implementation#13
medz merged 5 commits intomainfrom
fix/request-constructor-signature

Conversation

@medz
Copy link
Copy Markdown
Owner

@medz medz commented Mar 13, 2026

Summary by CodeRabbit

  • Refactor

    • Request constructor now accepts direct input types (Uri, String, or Request objects) instead of wrapped types, simplifying the API for creating requests.
    • Internal input handling refactored for consistency across implementations.
  • Tests

    • Tests updated to use the simplified Request constructor signature.
    • Added tests verifying request cloning behavior and init override handling.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 13, 2026

Warning

Rate limit exceeded

@medz has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 59 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f49b5285-6d67-465f-9c5e-277860a1e43a

📥 Commits

Reviewing files that changed from the base of the PR and between 8b8ac3a and 1743567.

📒 Files selected for processing (4)
  • lib/src/fetch/request.io.dart
  • lib/src/fetch/request.js.dart
  • test/request_io_test.dart
  • test/request_js_test.dart
📝 Walkthrough

Walkthrough

Changed Request construction to accept plain Object? (e.g., String, Uri, or Request) instead of public RequestInput wrappers; RequestInput types were privatized and input coercion is now internal.

Changes

Cohort / File(s) Summary
Call-site updates
example/main.dart, test/public_api_surface_test.dart, test/request_native_test.dart, test/request_io_test.dart, test/request_js_test.dart
Replaced RequestInput.*(...) wrappers with direct String, Uri, or Request arguments at Request construction sites; added new tests for cloning/override behavior.
Public exports removed
lib/src/fetch/request.dart
Removed public re-exports of RequestInput, RequestRequestInput, StringRequestInput, and UriRequestInput.
Native constructor refactor
lib/src/fetch/request.native.dart
Changed Request(RequestInput...)Request(Object?...); introduced private _RequestInput variants, _coerceInput()/_requireInput(), and private Request._() delegation; updated internal helper functions to use the private input types.
Platform-specific input handling
lib/src/fetch/request.io.dart, lib/src/fetch/request.js.dart
Simplified factory construction and native conversion: removed RequestInput wrappers in favor of direct native.Request(...) usage and streamlined cloning paths.
Test metadata additions
test/headers_test.dart, test/response_io_test.dart, test/url_search_params_test.dart
Added @TestOn('vm') and library; directives to VM-specific test files; no logic changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through code with nimble paws,
No wrappers now, just plain URIs,
I nudged the input behind closed doors,
Coercion hums and tests comply.
A little hop — the API sighs.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title uses vague language ('urgently correct broken') that doesn't clearly convey the specific technical change being made to the request implementation. Use a more descriptive title that clearly states the main change, such as: 'fix(fetch): simplify Request constructor to accept direct input types' or 'refactor(fetch): remove RequestInput wrapper from Request API'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/request-constructor-signature
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@medz medz changed the title fix(fetch): align request constructor semantics fix(fetch): urgently correct broken request implementation Mar 13, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/src/fetch/request.js.dart (1)

285-292: Defensive case at line 286 is unreachable but harmless.

The native.Request request when init == null case is already handled by the factory at line 39, so this branch in _toNativeRequest will never execute. The switch remains exhaustive and the code is correct, but this is effectively dead code.

Consider removing it for clarity, or keep it as defensive coding if you prefer robustness against future refactoring.

♻️ Optional: Remove unreachable case
   static native.Request _toNativeRequest(
     Object? input,
     native.RequestInit? init,
   ) {
     return switch (input) {
-      final native.Request request when init == null => request,
       final native.Request request => native.Request(request, init),
       final String _ => native.Request(input, init),
       final Uri _ => native.Request(input, init),
       final web.Request request => _nativeRequestFromWebRequest(request, init),
       _ => throw ArgumentError.value(input, 'input'),
     };
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/src/fetch/request.js.dart` around lines 285 - 292, Remove the unreachable
defensive pattern in the _toNativeRequest switch: delete the branch matching
"final native.Request request when init == null" since the factory (line ~39)
already guarantees that case; keep the other cases as-is so the switch remains
exhaustive and behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/src/fetch/request.io.dart`:
- Around line 28-33: The factory Request currently aliases existing request
wrappers (in the switch arms handling Request, io.HttpRequest, and
native.Request) which leads to duplicate Body instances; change those fast-path
arms in the Request factory to always rebuild a fresh native request via
native.Request(request, init) (or via the existing _toNativeRequest helper)
instead of returning the original wrapper/host (affecting Request(Object? input,
[native.RequestInit? init]), HttpRequestHost usage and NativeRequestHost usage),
and add a regression test that constructs Request(upstream) with null init to
assert only a single Body/stream is used (i.e., bodyUsed and reads remain
consistent).

In `@lib/src/fetch/request.native.dart`:
- Around line 370-381: Change the nullable parameter of _coerceInput from
Object? to non-null Object so the compile-time signature matches the Fetch API's
RequestInfo (which excludes null); update the declaration of
_coerceInput(Object? input) to _coerceInput(Object input) and ensure call sites
(e.g., any calls constructing Request that forward into _coerceInput) do not
pass null (or perform explicit null checks before calling) so the existing
ArgumentError path remains unnecessary for null values but the runtime behavior
for unsupported types is preserved.

---

Nitpick comments:
In `@lib/src/fetch/request.js.dart`:
- Around line 285-292: Remove the unreachable defensive pattern in the
_toNativeRequest switch: delete the branch matching "final native.Request
request when init == null" since the factory (line ~39) already guarantees that
case; keep the other cases as-is so the switch remains exhaustive and behavior
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f3f58bcd-aee4-479c-bf42-f2fc357f830f

📥 Commits

Reviewing files that changed from the base of the PR and between 893d9db and 2fa7041.

📒 Files selected for processing (12)
  • example/main.dart
  • lib/src/fetch/request.dart
  • lib/src/fetch/request.io.dart
  • lib/src/fetch/request.js.dart
  • lib/src/fetch/request.native.dart
  • test/headers_test.dart
  • test/public_api_surface_test.dart
  • test/request_io_test.dart
  • test/request_js_test.dart
  • test/request_native_test.dart
  • test/response_io_test.dart
  • test/url_search_params_test.dart
💤 Files with no reviewable changes (1)
  • lib/src/fetch/request.dart

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/src/fetch/request.io.dart`:
- Line 254: The current construction final Request request =>
native.Request(request.clone(), init) always clones the original request before
native.Request sees init, causing unnecessary cloning when init.body is
provided; change this so we only call request.clone() when init.body is null
(i.e., pass the original request when init.body != null and pass request.clone()
when init.body == null) so native.Request short-circuits correctly; update the
code path around the Request getter/constructor that references request.clone(),
native.Request, and init.body accordingly, and add a regression test that
rebuilds a consumed Request with RequestInit(body: ...) to verify the
replacement body is independent of the upstream request state.

In `@lib/src/fetch/request.js.dart`:
- Line 282: The current getter builds the wrapped Request by always calling
request.clone() which causes a body-override bug when init.body is provided;
change the logic in the Request getter so it only calls request.clone() when
init?.body == null and otherwise pass the original upstream request (or a
non-cloned reference) into native.Request along with the RequestInit(body: ...);
update the code around the Request getter that returns
native.Request(request.clone(), init) to conditionally use request.clone() only
when init?.body == null, ensuring RequestInit(body: ...) is applied without
requiring the upstream body to be cloneable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12e84c34-c592-4fab-815e-d8a841a5e098

📥 Commits

Reviewing files that changed from the base of the PR and between 2fa7041 and 8b8ac3a.

📒 Files selected for processing (5)
  • lib/src/fetch/request.io.dart
  • lib/src/fetch/request.js.dart
  • lib/src/fetch/request.native.dart
  • test/request_io_test.dart
  • test/request_js_test.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/request_js_test.dart

@medz medz merged commit 401425c into main Mar 13, 2026
2 checks passed
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