Practical Implementation
Real-World Exception Handling Scenario
Banking Application Example
public class BankingService {
public void transferFunds(Account source, Account destination, double amount)
throws InsufficientFundsException, AccountBlockedException {
// Validate account status
if (source.isBlocked() || destination.isBlocked()) {
throw new AccountBlockedException("One or both accounts are blocked");
}
// Check sufficient balance
if (source.getBalance() < amount) {
throw new InsufficientFundsException(
"Insufficient funds",
source.getAccountNumber(),
amount
);
}
// Perform transfer logic
source.withdraw(amount);
destination.deposit(amount);
}
}
Custom Exception Hierarchy
graph TD
A[BaseBusinessException] --> B[InsufficientFundsException]
A --> C[AccountBlockedException]
A --> D[TransactionLimitException]
Exception Design Patterns
Pattern |
Description |
Use Case |
Wrapper Exception |
Encapsulates low-level exceptions |
Complex error translation |
Context Exception |
Adds contextual information |
Detailed error reporting |
Chained Exception |
Preserves original exception cause |
Root cause analysis |
Comprehensive Exception Implementation
public class InsufficientFundsException extends Exception {
private final String accountNumber;
private final double requestedAmount;
private final double currentBalance;
public InsufficientFundsException(
String message,
String accountNumber,
double requestedAmount
) {
super(message);
this.accountNumber = accountNumber;
this.requestedAmount = requestedAmount;
this.currentBalance = getCurrentAccountBalance(accountNumber);
}
public String getAccountNumber() {
return accountNumber;
}
public double getRequestedAmount() {
return requestedAmount;
}
public double getCurrentBalance() {
return currentBalance;
}
@Override
public String toString() {
return String.format(
"Insufficient Funds: Account %s, Requested: $%.2f, Available: $%.2f",
accountNumber,
requestedAmount,
currentBalance
);
}
}
Error Handling Strategy
public class TransactionProcessor {
public void processTransaction(Transaction transaction) {
try {
validateTransaction(transaction);
executeTransaction(transaction);
} catch (InsufficientFundsException e) {
// Log detailed error
logger.error(e.toString());
// Notify user or take alternative action
notifyInsufficientFunds(e);
} catch (AccountBlockedException e) {
// Handle blocked account scenario
suspendTransaction(transaction);
} catch (Exception e) {
// Fallback error handling
handleUnexpectedError(e);
}
}
}
Exception Logging Best Practices
- Use structured logging
- Include contextual information
- Log at appropriate levels
- Avoid logging sensitive data
- Use exception chaining
Advanced Techniques
- Create custom exception mappers
- Implement global error handling
- Use exception translators
- Design fault-tolerant systems
LabEx recommends developing a comprehensive exception handling strategy that balances error detection, reporting, and system resilience. Effective exception design improves application reliability and user experience.