Commit 4333700
authored
[go_router] Fix chained top-level redirects not being fully resolved (#11108)
Fixes flutter/flutter#178984
The `onEnter` refactor (commit `9ec29b6d23`, PR #8339) split the unified `redirect()` method into `applyTopLegacyRedirect()` (top-level, runs once) and `redirect()` (route-level only). This introduced two regressions:
1. **Top-level redirect chains broken**: `applyTopLegacyRedirect()` returned after one hop — a chain like `/ → /a → /b` stopped at `/a` instead of resolving to `/b`.
2. **Route-level → top-level chains broken**: `processRouteLevelRedirect()` recursed into `redirect()` without re-evaluating the top-level redirect on the new location.
### Fix
Unify top-level and route-level redirects back into `redirect()` as the single entry point for all redirect processing, while keeping the separation of concerns via `applyTopLegacyRedirect()` as an internal helper.
> **Note:** An earlier revision of this PR (v1) kept the split but added recursive calls in both methods. Based on [reviewer feedback](#11108 (comment)), the approach was refactored to move `applyTopLegacyRedirect()` inside `redirect()` so the caller (`parseRouteInformationWithDependencies`) doesn't need to know about the two-phase process.
#### Before (broken)
```mermaid
sequenceDiagram
participant Parser as parseRouteInformationWithDependencies
participant TopRedir as applyTopLegacyRedirect
participant Redir as redirect (route-level only)
Parser->>TopRedir: / (one hop only)
TopRedir-->>Parser: /a (stops here ✗)
Parser->>Redir: /a
Redir->>Redir: route-level redirects
Note right of Redir: No top-level re-evaluation
Redir-->>Parser: result
```
#### After (fix)
```mermaid
sequenceDiagram
participant Parser as parseRouteInformationWithDependencies
participant Redir as redirect (unified)
participant TopRedir as applyTopLegacyRedirect
Parser->>Redir: / (initial matches)
Redir->>TopRedir: / → top-level redirect chain
TopRedir->>TopRedir: / → /a → /b (self-recursive)
TopRedir-->>Redir: /b (fully resolved ✓)
Redir->>Redir: route-level redirects on /b
Note right of Redir: If route-level changes location,<br/>recurse → top-level re-evaluated
Redir-->>Parser: final result
```
#### Key changes
- **`configuration.dart` — `redirect()`**: Now calls `applyTopLegacyRedirect()` first at every cycle, then processes route-level redirects on the post-top-level result. Route-level `_processRouteLevelRedirects` extracted as a helper.
- **`configuration.dart` — `applyTopLegacyRedirect()`**: Self-recursive to fully resolve top-level chains. No functional change from v1.
- **`parser.dart` — `parseRouteInformationWithDependencies()`**: Simplified — no longer calls `applyTopLegacyRedirect` separately. Just passes initial matches to `_navigate()`.
- **`parser.dart` — `_navigate()`**: Removed `preSharedHistory` parameter. Added `context.mounted` guard in the result `.then()` to protect the relocated async boundary.
Both fixes share the existing `redirectHistory` for loop detection and respect `redirectLimit`. The `onEnter` system is completely unaffected — it runs before redirects in the pipeline.
### Tests
- **19 redirect chain tests** (`redirect_chain_test.dart`): top-level chains, async chains, loop detection (including loop-to-initial), route→top cross-type chains, **async cross-type chains** (async top→route, async route→sync top, sync route→async top), **context disposal** during async top-level and route-level redirects, redirect limit boundary (exact limit succeeds, limit+1 fails), shared limit across redirect types.
- **3 onEnter interaction tests** (`on_enter_test.dart`): onEnter called once when chains resolve, onEnter block prevents redirect evaluation.
- **Full suite**: 418 tests pass, 0 regressions.
## Pre-Review Checklist
[^1]: This PR uses `pending_changelogs/` for versioning and changelog, following the go_router batch release process.1 parent c780d2d commit 4333700
File tree
5 files changed
+1191
-112
lines changed- packages/go_router
- lib/src
- pending_changelogs
- test
5 files changed
+1191
-112
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
252 | | - | |
| 252 | + | |
253 | 253 | | |
254 | 254 | | |
255 | 255 | | |
| |||
401 | 401 | | |
402 | 402 | | |
403 | 403 | | |
404 | | - | |
| 404 | + | |
| 405 | + | |
405 | 406 | | |
406 | | - | |
407 | | - | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
408 | 411 | | |
409 | 412 | | |
410 | 413 | | |
411 | 414 | | |
412 | 415 | | |
413 | 416 | | |
414 | | - | |
415 | | - | |
416 | | - | |
417 | | - | |
418 | | - | |
419 | | - | |
420 | | - | |
421 | | - | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
426 | 423 | | |
427 | | - | |
428 | | - | |
429 | | - | |
430 | | - | |
431 | | - | |
432 | | - | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
433 | 431 | | |
434 | | - | |
435 | | - | |
436 | | - | |
437 | | - | |
438 | | - | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
439 | 435 | | |
440 | | - | |
| 436 | + | |
441 | 437 | | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
442 | 445 | | |
443 | | - | |
444 | | - | |
445 | | - | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
446 | 456 | | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | | - | |
451 | | - | |
452 | | - | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
459 | | - | |
460 | | - | |
461 | | - | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
468 | | - | |
469 | | - | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
470 | 466 | | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
471 | 474 | | |
| 475 | + | |
472 | 476 | | |
473 | 477 | | |
474 | | - | |
475 | | - | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
476 | 518 | | |
477 | | - | |
478 | 519 | | |
479 | 520 | | |
480 | 521 | | |
| |||
484 | 525 | | |
485 | 526 | | |
486 | 527 | | |
487 | | - | |
488 | | - | |
489 | | - | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
490 | 532 | | |
491 | 533 | | |
492 | 534 | | |
| |||
500 | 542 | | |
501 | 543 | | |
502 | 544 | | |
503 | | - | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
504 | 554 | | |
505 | 555 | | |
506 | 556 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
114 | | - | |
| 114 | + | |
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
120 | | - | |
121 | 120 | | |
122 | 121 | | |
123 | 122 | | |
124 | 123 | | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
162 | 130 | | |
163 | 131 | | |
164 | 132 | | |
| |||
198 | 166 | | |
199 | 167 | | |
200 | 168 | | |
201 | | - | |
202 | 169 | | |
203 | 170 | | |
204 | 171 | | |
205 | 172 | | |
206 | 173 | | |
207 | 174 | | |
208 | 175 | | |
209 | | - | |
210 | | - | |
211 | | - | |
| 176 | + | |
212 | 177 | | |
213 | | - | |
| 178 | + | |
| 179 | + | |
214 | 180 | | |
215 | 181 | | |
216 | 182 | | |
| |||
222 | 188 | | |
223 | 189 | | |
224 | 190 | | |
225 | | - | |
| 191 | + | |
226 | 192 | | |
227 | 193 | | |
228 | 194 | | |
229 | 195 | | |
230 | | - | |
231 | 196 | | |
232 | 197 | | |
233 | 198 | | |
234 | | - | |
235 | | - | |
| 199 | + | |
236 | 200 | | |
237 | 201 | | |
238 | 202 | | |
239 | 203 | | |
240 | 204 | | |
241 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
242 | 217 | | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | 218 | | |
247 | 219 | | |
248 | 220 | | |
| |||
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
0 commit comments