All skills
Skillintermediate
Code Quality Checklist
- **Swallowed exceptions**: Empty catch blocks or catch with only logging. Example: ```java try { ... } catch (Exception e) { } // Silent failure try { ... } catch (Exception e) { e.printStackTrace(); } // Log and forget, no re-throw ``` - **Overly broad catch**: Catching `Exception` or `Throwable` instead of specific types - **Error information leakage**: Stack traces or internal details exposed
Claude Code Knowledge Pack7/10/2026
Overview
Code Quality Checklist
Contents
- Error Handling (anti-patterns, best practices, questions)
- Performance & Caching (CPU, database/IO, caching, memory)
- Boundary Conditions (null handling, empty collections, numeric, string)
Error Handling
Anti-patterns to Flag
- Swallowed exceptions: Empty catch blocks or catch with only logging. Example:
try { ... } catch (Exception e) { } // Silent failure try { ... } catch (Exception e) { e.printStackTrace(); } // Log and forget, no re-throw - Overly broad catch: Catching
ExceptionorThrowableinstead of specific types - Error information leakage: Stack traces or internal details exposed to users
- Missing error handling: Unchecked exceptions from I/O, network, or parsing operations not anticipated
- Checked exception abuse: Declaring
throws Exceptioninstead of specific types, wrapping checked exceptions inRuntimeExceptionwithout cause chaining - CompletableFuture error handling: Missing
.exceptionally()or.handle(), unobserved exceptions in async chains
Best Practices to Check
- Errors are caught at appropriate boundaries
- Error messages are user-friendly (no internal details exposed)
- Errors are logged with sufficient context for debugging
- Async/CompletableFuture exceptions are handled, not silently dropped
- Fallback behavior is defined for recoverable errors
- Critical errors trigger alerts/monitoring
Questions to Ask
- "What happens when this operation fails?"
- "Will the caller know something went wrong?"
- "Is there enough context to debug this error?"
Performance & Caching
CPU-Intensive Operations
- Expensive operations in hot paths:
Pattern.compilein loops, JSON parsing in hot paths, crypto in loops - Blocking request threads: Blocking I/O on reactor/virtual threads, heavy computation without offloading
- Unnecessary recomputation: Same calculation done multiple times
- Autoboxing in hot paths: Repeated
int/Integerboxing in tight loops - Stream API pitfalls: Parallel streams on shared mutable state, stateful lambdas in
map/filterchains, side effects inforEach
Database & I/O
- N+1 queries: Loop that makes a query per item instead of batch
// Bad: N+1 for (Long id : ids) { User user = em.find(User.class, id); } // Good: Batch List users = em.createQuery( "SELECT u FROM User u WHERE u.id IN :ids", User.class) .setParameter("ids", ids).getResultList(); - Missing indexes: Queries on unindexed columns
- Over-fetching: SELECT * when only few columns needed; eager fetching entire object graphs
- No pagination: Loading entire dataset into memory
Caching Issues
- Missing cache for expensive operations: Repeated API calls, DB queries, computations
- Cache without TTL: Stale data served indefinitely
- Cache without invalidation strategy: Data updated but cache not cleared
- Cache key collisions: Insufficient key uniqueness
- Caching user-specific data globally: Security/privacy issue
Memory
- Unbounded collections:
ArrayList/HashMapthat grow without limit - Large object retention: Holding references preventing GC
- String concatenation in loops: Use
StringBuilderinstead - Loading large files entirely: Use
InputStream/BufferedReaderstreaming instead - Resource leaks: Missing
try-with-resourcesforCloseable/AutoCloseableresources equals/hashCodecontract: OverridingequalswithouthashCode(or vice versa) — breaksHashMap/HashSetbehavior==vs.equals()for strings: Reference comparison instead of value comparison forStringand boxed types (Integer,Long)ConcurrentModificationException: Modifying a collection duringfor-eachiteration — useIterator.remove()or concurrent collections
Questions to Ask
- "What's the time complexity of this operation?"
- "How does this behave with 10x/100x data?"
- "Is this result cacheable? Should it be?"
- "Can this be batched instead of one-by-one?"
Boundary Conditions
Null Handling
- Missing null checks: Accessing methods on potentially null references (causes
NullPointerException) - Optional misuse:
Optional.get()withoutisPresent(), usingOptionalas field type - Nullable annotations ignored:
@Nullablereturn values used without checks - Null vs empty inconsistency: Mixed usage of
nulland empty collections/strings without clear convention
Empty Collections
- Empty list not handled: Code assumes list has items
- Empty map edge case: Key access or iteration on empty map
- First/last element access:
list.get(0)orlist.get(list.size()-1)without size check
Numeric Boundaries
- Division by zero: Missing check before division (throws
ArithmeticException) - Integer overflow:
intwrapping atInteger.MAX_VALUE, unchecked cast fromlongtoint - Floating point comparison: Using
==instead of epsilon comparison orBigDecimal - Negative values: Index or count that shouldn't be negative
- Off-by-one errors: Loop bounds,
subList, pagination
String Boundaries
- Empty string: Not handled as edge case
- Whitespace-only string: Passes non-null check but is effectively empty
- Very long strings: No length limits causing memory/display issues
- Unicode edge cases: Emoji, RTL text, surrogate pairs
Common Patterns to Flag
// Dangerous: no null check (NullPointerException if user or getProfile() is null)
String name = user.getProfile().getName();
// Dangerous: list access without check (IndexOutOfBoundsException if items is empty)
Item first = items.get(0);
// Dangerous: division without check (ArithmeticException if count is 0)
int avg = total / count;
// Dangerous: Optional.get without check
String value = optional.get(); // NoSuchElementException if empty
Questions to Ask
- "What if this is null?"
- "What if this collection is empty?"
- "What's the valid range for this number?"
- "What happens at the boundaries (0, -1, Integer.MAX_VALUE)?"