Interview question
What are best practices for logging and debugging exceptions in production Java applications? Production Java applications में exceptions log और debug करने की best practices क्या हैं?
Answer
| Practice | Why it matters |
|---|---|
| Use a logging framework (SLF4J, Log4j), not System.out | Configurable levels, output destinations, and performance |
| Log the full stack trace | Root cause is often deep in the chain, not just the top message |
| Never swallow exceptions silently | Empty catch blocks hide real problems |
| Include context in log messages | User ID, request ID, operation name help correlate issues |
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
public void processOrder(String orderId) {
try {
// ... processing logic ...
} catch (Exception e) {
// GOOD: logs message, context, AND full stack trace
logger.error('Failed to process order {}: {}', orderId, e.getMessage(), e);
throw new RuntimeException('Order processing failed', e); // rethrow, don't swallow
}
}
}
// BAD PRACTICE - silently swallowing exceptions
public void badExample() {
try {
riskyOperation();
} catch (Exception e) {
// empty catch block - error disappears completely, very hard to debug later
}
}
// BAD PRACTICE - printStackTrace() only, no structured logging
catch (Exception e) {
e.printStackTrace(); // goes to console only, lost in production, no log levels
}
// GOOD - catching specific exceptions, not blanket 'catch (Exception e)' everywhere
try {
parseInput(data);
} catch (NumberFormatException e) {
logger.warn('Invalid number format in input: {}', data);
} catch (IllegalArgumentException e) {
logger.warn('Invalid argument: {}', e.getMessage());
}
// Blanket catches make it hard to know what specifically went wrong| Practice | क्यों important है |
|---|---|
| Logging framework use करना, System.out नहीं | Configurable levels, destinations |
| पूरा stack trace log करना | Root cause अक्सर chain में गहरा होता है |
| Exceptions चुपचाप swallow न करना | Empty catch blocks real problems छुपाते हैं |
| Log messages में context शामिल करना | User ID, request ID debugging में मदद करते हैं |
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
public void processOrder(String orderId) {
try {
// ... processing ...
} catch (Exception e) {
logger.error('Failed to process order {}: {}', orderId, e.getMessage(), e);
throw new RuntimeException('Order processing failed', e);
}
}
}
// गलत practice - चुपचाप swallow करना
public void badExample() {
try {
riskyOperation();
} catch (Exception e) {
// empty catch block - error पूरी तरह गायब हो जाती है
}
}
// गलत practice - सिर्फ printStackTrace()
catch (Exception e) {
e.printStackTrace(); // production में खो जाता है
}
// सही - specific exceptions catch करना
try {
parseInput(data);
} catch (NumberFormatException e) {
logger.warn('Invalid number format: {}', data);
} catch (IllegalArgumentException e) {
logger.warn('Invalid argument: {}', e.getMessage());
}Was this answer clear?