| MAUI-HttpClient-CRUD :👈 | 👉:MAUI-Cancellation-Token |
REST API consumer in MAUI with error handling |
REST API consumer in MAUI with error handling so your app stays resilient when the network fails, the server responds incorrectly, or the user is offline.
π‘οΈ Error Handling with HttpClient
1. Wrap Calls in try/catch
Every API call should be protected:
public async Task<List<Post>> GetPostsAsync()
{
try
{
return await _httpClient.GetFromJsonAsync<List<Post>>("posts");
}
catch (HttpRequestException ex)
{
// Network or server unreachable
Console.WriteLine($"Network error: {ex.Message}");
return new List<Post>();
}
catch (NotSupportedException ex)
{
// Content type not supported
Console.WriteLine($"Unsupported content: {ex.Message}");
return new List<Post>();
}
catch (JsonException ex)
{
// Invalid JSON
Console.WriteLine($"Invalid JSON: {ex.Message}");
return new List<Post>();
}
}
2. Use EnsureSuccessStatusCode
This throws if the response isnβt 2xx:
var response = await _httpClient.PostAsJsonAsync("posts", newPost);
response.EnsureSuccessStatusCode();
Wrap in try/catch to handle gracefully.
3. Provide User-Friendly Feedback
Instead of just logging, surface messages in the UI:
public async Task<string> SafeCreatePostAsync(Post newPost)
{
try
{
var response = await _httpClient.PostAsJsonAsync("posts", newPost);
response.EnsureSuccessStatusCode();
return "Post created successfully!";
}
catch (Exception ex)
{
return $"Failed to create post: {ex.Message}";
}
}
4. ViewModel Example
Add a property for error messages:
private string _errorMessage;
public string ErrorMessage
{
get => _errorMessage;
set { _errorMessage = value; OnPropertyChanged(); }
}
public async Task LoadPosts()
{
try
{
var posts = await _api.GetPostsAsync();
Posts.Clear();
foreach (var post in posts)
Posts.Add(post);
ErrorMessage = string.Empty;
}
catch (Exception ex)
{
ErrorMessage = $"Could not load posts: {ex.Message}";
}
}
5. UI Binding
Show errors in your page:
<Label Text="{Binding ErrorMessage}" TextColor="Red" />
β Benefits
- Prevents app crashes.
- Gives clear feedback to users.
- Handles offline scenarios gracefully.
- Keeps logs for debugging.
Retry Logic with Exponential Backoff in MAUI
adding retry logic with exponential backoff makes your MAUI app much more resilient when consuming REST APIs. Instead of failing immediately on a network hiccup, the app will retry a few times with increasing delays before showing an error.
π Retry Logic with Exponential Backoff
1. Helper Method
You can wrap your API calls in a retry loop:
private async Task<T> ExecuteWithRetry<T>(Func<Task<T>> operation, int maxRetries = 3)
{
int delay = 1000; // start with 1 second
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
return await operation();
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Attempt {attempt} failed: {ex.Message}");
if (attempt == maxRetries)
throw; // rethrow after last attempt
}
await Task.Delay(delay);
delay *= 2; // exponential backoff
}
throw new Exception("Operation failed after retries.");
}
2. Use It in Your Service
Wrap your API calls:
public async Task<List<Post>> GetPostsAsync()
{
return await ExecuteWithRetry(async () =>
{
return await _httpClient.GetFromJsonAsync<List<Post>>("posts");
});
}
3. Apply to Other Methods
You can reuse ExecuteWithRetry for POST, PUT, and DELETE:
public async Task<Post> CreatePostAsync(Post newPost)
{
return await ExecuteWithRetry(async () =>
{
var response = await _httpClient.PostAsJsonAsync("posts", newPost);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<Post>();
});
}
4. User-Friendly Feedback
In your ViewModel, catch the final exception and surface a message:
public async Task LoadPosts()
{
try
{
var posts = await _api.GetPostsAsync();
Posts.Clear();
foreach (var post in posts)
Posts.Add(post);
ErrorMessage = string.Empty;
}
catch (Exception ex)
{
ErrorMessage = $"Could not load posts after retries: {ex.Message}";
}
}
β Benefits
- Handles temporary network glitches.
- Avoids overwhelming the server with rapid retries.
- Provides clear feedback if all attempts fail.
- Keeps your app responsive and user-friendly.
| MAUI-HttpClient-CRUD :👈 | 👉:MAUI-Cancellation-Token |