Introduction
Network requests can fail for many reasons: no internet, timeouts, server errors (5xx), or rate limiting. A robust app should be able to retry these requests automatically or give users the option to retry. GetX, combined with an HTTP client like Dio, provides powerful tools to implement retry logic with minimal boilerplate. This guide covers strategies for automatic retries with exponential backoff, user‑triggered retries, and integrating retry state into your GetX controllers.
- Simple Retry with Recursion
The simplest way to implement a retry is to call the same function recursively on failure. This gives you full control over the retry count and delay.
- Using Dio Interceptor for Retry
If you use Dio, the dio_retry package provides a ready‑made interceptor. You can also write your own interceptor for fine‑grained control.
- Exponential Backoff with Jitter
Exponential backoff (increasing delay between retries) prevents overwhelming the server. Adding a small random jitter helps avoid thundering herd problems when many clients retry simultaneously.
- User‑Triggered Retry with GetX
Sometimes you want to let the user decide when to retry (e.g., after showing an error message). Use a reactive boolean to indicate a retry state and expose a method that the UI can call.
- Automatic Retry with GetX Workers
You can combine a retry mechanism with a worker that listens to an error state and automatically retries after a delay.
- Showing Retry Progress
When retrying automatically, you may want to show a countdown or a message like "Retrying in X seconds…" to inform the user.
- Handling Idempotent Requests
Not all requests are safe to retry automatically (e.g., POST requests that create resources). Always check if the request is idempotent before retrying. For Dio, you can check the HTTP method.
Best Practices
- Limit retries – Usually 3‑5 attempts maximum.
- Use exponential backoff – Prevents overwhelming the server.
- Add jitter – Avoids thundering herd problems.
- Only retry idempotent requests – Avoid duplicating non‑idempotent operations (e.g., POST).
- Notify the user – Show a message when retrying automatically, or provide a manual retry button.
- Cancel retries on navigation – If the user leaves the screen, cancel ongoing retry timers.
- Test retry logic – Simulate network failures to ensure retries work correctly.
Common Mistakes
- ❌ Retrying POST/PATCH requests – May create duplicate records. ✅ Only retry idempotent requests.
- ❌ Infinite retries – Without a max limit, may loop forever. ✅ Always set a maximum retry count.
- ❌ Immediate retries – Causes cascading failures; always add a delay. ✅ Use backoff strategies.
- ❌ Not handling retry cancellation – Timers may fire after the controller is disposed.
✅ Cancel timers in
onClose.
FAQ
- Q: Should I retry on 401 (Unauthorized)?
A: Usually no. 401 means the token is invalid; you should refresh the token or redirect to login. - Q: How do I retry only on certain error types?
A: In your retry logic, check the exception type or status code and returntrueonly for those you want to retry. - Q: Can I combine automatic and manual retry?
A: Yes, provide a manual retry button that resets the retry counter and calls the same fetch method. - Q: Does
dio_retrywork with GetX?
A: Yes, just add it as an interceptor in yourApiService. It will automatically retry according to your configuration. - Q: How to test retry logic?
A: Use mockito to throw exceptions on the first few calls, then succeed on the third. Verify the number of attempts.
Conclusion
Implementing network retry is crucial for building resilient Flutter apps. GetX provides the flexibility to implement both automatic and manual retries, integrate with Dio interceptors, and manage retry state reactively. By following the patterns in this guide, you can ensure your app gracefully recovers from transient network issues.