Defensive Programming Vs Fail Fast · How it works

1 min read
Mid-level3 min read
Rapid overview

How it works

A comprehensive guide to two fundamental error handling philosophies in software development.


Real-World Trading System Example

public class TradingSystem
{
    // Defensive: External market data feed
    public async Task<MarketPrice> GetMarketPriceAsync(string symbol)
    {
        try
        {
            var rawData = await _marketDataFeed.GetPriceAsync(symbol);

            // Defensive: validate external data
            if (rawData == null || string.IsNullOrEmpty(rawData.Price))
            {
                _logger.LogWarning("Invalid market data for {Symbol}", symbol);
                return await GetCachedPriceAsync(symbol); // Fallback
            }

            if (!decimal.TryParse(rawData.Price, out var price) || price <= 0)
            {
                _logger.LogWarning("Invalid price format: {Price}", rawData.Price);
                return await GetCachedPriceAsync(symbol); // Fallback
            }

            return new MarketPrice(symbol, price, DateTime.UtcNow);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Market data feed error for {Symbol}", symbol);
            return await GetCachedPriceAsync(symbol); // Fallback
        }
    }

    // Fail-Fast: Internal order execution
    public async Task ExecuteOrderAsync(Order order, decimal executionPrice)
    {
        // Fail-fast: validate preconditions
        if (order == null)
            throw new ArgumentNullException(nameof(order));

        if (order.Status != OrderStatus.Pending)
            throw new InvalidOperationException(
                $"Cannot execute order in {order.Status} status");

        if (executionPrice <= 0)
            throw new ArgumentException(
                "Execution price must be positive", nameof(executionPrice));

        // Fail-fast: check risk limits
        var account = await _accountRepository.GetByIdAsync(order.AccountId);
        if (account == null)
            throw new InvalidOperationException(
                $"Account {order.AccountId} not found");

        _riskValidator.ValidateExecution(order, account, executionPrice);

        // Execute
        order.Execute(executionPrice);
        account.UpdatePosition(order);

        await _unitOfWork.CommitAsync();
    }
}

See also