Md Mominul Islam | Software and Data Enginnering | SQL Server, .NET, Power BI, Azure Blog

while(!(succeed=try()));

LinkedIn Portfolio Banner

Latest

Home Top Ad

Responsive Ads Here

Post Top Ad

Responsive Ads Here

Wednesday, September 10, 2025

How to Handle Timeout Errors in ASP.NET Core Web API

 

How to Handle Timeout Errors in ASP.NET Core Web API

Handling timeout errors in ASP.NET Core Web API is critical for ensuring robust and reliable applications, especially in business-critical systems where downtime or slow responses can lead to lost revenue or poor user experience. This article provides a detailed, step-by-step guide to configuring and managing timeout errors in ASP.NET Core Web APIs, complete with practical code examples, real-world use cases, and a discussion of pros and cons.

Understanding Timeout Errors in ASP.NET Core

Timeout errors occur when an API request takes longer than the configured time limit to process, resulting in the server or client terminating the connection. These errors can stem from various sources, such as slow database queries, external service delays, or high server load. In ASP.NET Core, timeout handling involves configuring both server-side and client-side settings to balance performance, reliability, and user experience.

Common Timeout Scenarios

  • Database Queries: Long-running queries or deadlocks in the database.

  • External APIs: Third-party services taking too long to respond.

  • Heavy Processing: Complex computations or large data processing on the server.

  • Network Issues: Slow or unreliable network connections between client and server.

Step-by-Step Guide to Handling Timeout Errors

Step 1: Configure Server-Side Timeout in ASP.NET Core

ASP.NET Core allows you to set timeouts at various levels, such as the web server (Kestrel), middleware, or individual controllers. Below are key approaches to configure server-side timeouts.

Configure Kestrel Server Timeout

Kestrel, the default web server in ASP.NET Core, supports request timeout configuration. You can set a global timeout for all requests.

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Configure Kestrel server options
builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(30); // Timeout for keep-alive connections
    options.Limits.RequestTimeout = TimeSpan.FromSeconds(20); // Timeout for individual requests
});

builder.Services.AddControllers();
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.Run();

Explanation:

  • KeepAliveTimeout: Specifies how long a connection can remain idle before being closed.

  • RequestTimeout: Sets the maximum time allowed for processing a single request.

Real-Life Usage: In a business application like an e-commerce platform, setting a RequestTimeout of 20 seconds ensures that slow API calls (e.g., fetching product details) don't hang the server, improving responsiveness during peak traffic.

Use Timeout Middleware

ASP.NET Core provides a TimeoutMiddleware to enforce timeouts on specific endpoints or globally. This middleware can be added to the request pipeline.

// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();

var app = builder.Build();
app.UseRouting();

// Add Timeout Middleware
app.Use(async (context, next) =>
{
    context.SetEndpointTimeout(TimeSpan.FromSeconds(15));
    await next();
});

app.MapControllers();
app.Run();

Explanation: The middleware sets a timeout for each request. If the request exceeds the specified time, it throws a TimeoutException, which you can handle gracefully.

Business Scenario: In a financial services API, where quick responses are critical for stock trading, a 15-second timeout ensures that delayed responses don't disrupt time-sensitive transactions.

Step 2: Handle Timeout Exceptions

To provide meaningful feedback to clients, catch and handle timeout exceptions in your API.

// Middleware/ExceptionMiddleware.cs
public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public ExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (TimeoutException)
        {
            context.Response.StatusCode = StatusCodes.Status408RequestTimeout;
            await context.Response.WriteAsync("Request timed out. Please try again later.");
        }
        catch (Exception ex)
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await context.Response.WriteAsync($"An error occurred: {ex.Message}");
        }
    }
}

// Program.cs
var app = builder.Build();
app.UseMiddleware<ExceptionMiddleware>();
app.UseRouting();
app.MapControllers();
app.Run();

Explanation: This custom middleware catches TimeoutException and returns a 408 Request Timeout status code with a user-friendly message.

Real-Life Example: In a healthcare API managing patient records, catching timeout exceptions prevents users from seeing generic errors and provides clear instructions to retry, improving user trust.

Step 3: Optimize Long-Running Operations

Timeouts often occur due to inefficient code or external dependencies. Optimize these operations to reduce timeout occurrences.

Example: Optimize Database Queries

Use asynchronous database calls and indexing to improve performance.

// Controllers/ProductsController.cs
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    private readonly AppDbContext _context;

    public ProductsController(AppDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<IActionResult> GetProducts(CancellationToken cancellationToken)
    {
        try
        {
            // Use async and cancellation token
            var products = await _context.Products
                .AsNoTracking()
                .Take(100)
                .ToListAsync(cancellationToken);
            return Ok(products);
        }
        catch (OperationCanceledException)
        {
            return StatusCode(408, "Request timed out while fetching products.");
        }
    }
}

Explanation:

  • AsNoTracking(): Improves performance by disabling change tracking for read-only queries.

  • Take(100): Limits the number of records to prevent large data transfers.

  • CancellationToken: Allows the request to be canceled if it exceeds the timeout.

Business Usage: In a retail API, optimizing database queries ensures that product listings load quickly during flash sales, reducing timeout errors under high load.

Example: Handle External API Calls

When calling external services, use HttpClient with a timeout configuration.

// Services/ExternalService.cs
public class ExternalService
{
    private readonly HttpClient _httpClient;

    public ExternalService()
    {
        _httpClient = new HttpClient
        {
            Timeout = TimeSpan.FromSeconds(10)
        };
    }

    public async Task<string> GetExternalDataAsync()
    {
        try
        {
            var response = await _httpClient.GetAsync("https://api.example.com/data");
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
        catch (TaskCanceledException)
        {
            throw new TimeoutException("External API request timed out.");
        }
    }
}

Explanation: Setting HttpClient.Timeout ensures that external API calls don't hang indefinitely. The TaskCanceledException is caught and converted to a TimeoutException for consistent error handling.

Real-Life Scenario: In a logistics API integrating with a shipping provider, a 10-second timeout prevents delays in tracking updates, ensuring timely delivery information.

Step 4: Configure Client-Side Timeout

Clients consuming your API should also handle timeouts gracefully. For example, in a .NET client:

// ClientApp/Program.cs
var client = new HttpClient
{
    Timeout = TimeSpan.FromSeconds(15)
};

try
{
    var response = await client.GetAsync("https://your-api.com/products");
    response.EnsureSuccessStatusCode();
    Console.WriteLine(await response.Content.ReadAsStringAsync());
}
catch (TaskCanceledException)
{
    Console.WriteLine("Request to API timed out. Please try again.");
}

Explanation: The client sets a timeout to avoid waiting indefinitely. If the server doesn't respond in time, the client handles the TaskCanceledException and informs the user.

Business Application: In a mobile banking app, client-side timeout handling ensures users aren't stuck waiting during server slowdowns, prompting them to retry or contact support.

Step 5: Monitor and Log Timeout Errors

Use logging and monitoring tools like Serilog or Application Insights to track timeout errors and identify bottlenecks.

// Program.cs
builder.Services.AddApplicationInsightsTelemetry();
builder.Logging.AddSerilog(new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/timeout-errors.txt")
    .CreateLogger());

var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.Run();

Explanation: Logging timeout errors helps developers identify patterns, such as frequent timeouts during specific operations, enabling targeted optimizations.

Business Use Case: In a SaaS platform, monitoring timeout errors helps the operations team proactively address performance issues before they impact customers.

Pros and Cons of Timeout Handling in ASP.NET Core

Pros

  • Improved Reliability: Prevents the server from being overwhelmed by long-running requests.

  • Better User Experience: Provides clear error messages instead of leaving users hanging.

  • Scalability: Helps manage resources efficiently under high load.

  • Customizable: Allows fine-grained control over timeouts at different layers (server, middleware, client).

Cons

  • Complexity: Requires careful configuration to avoid premature timeouts or overly long waits.

  • Potential Data Loss: Canceling requests may interrupt operations, leading to incomplete data processing.

  • Tuning Challenges: Finding the right timeout duration requires testing and monitoring, as it depends on the application's needs.

Real-Life Usage in Business

  • E-Commerce: Timeout handling ensures product searches and checkout processes remain responsive during high-traffic events like Black Friday.

  • Healthcare: APIs for patient data retrieval use timeouts to prevent delays in critical systems, ensuring doctors get timely access to records.

  • Finance: In trading platforms, timeouts prevent stalled transactions, maintaining market competitiveness.

  • Logistics: APIs integrating with external shipping services use timeouts to avoid delays in tracking or delivery updates.

No comments:

Post a Comment

Thanks for your valuable comment...........
Md. Mominul Islam

Post Bottom Ad

Responsive Ads Here