Skip to content

Commit bbb987e

Browse files
authored
Merge branch 'main' into test_azure
Signed-off-by: rupali-atlan <[email protected]>
2 parents 19b38a5 + 759a0ae commit bbb987e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+4842
-1127
lines changed

.cursor/BUGBOT.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Project Review Guidelines - Application SDK
2+
3+
## Core Principles
4+
5+
**Less Code is Better** - Prioritize simplicity, readability, and maintainability over cleverness. Every line of code is a liability that must be justified.
6+
7+
## Critical Review Checklist
8+
9+
### 🔍 Code Quality & Minimalism
10+
11+
- **Necessity Check**: Is this code absolutely necessary? Can existing functionality be reused?
12+
- **Single Responsibility**: Does each function/class do exactly one thing well?
13+
- **DRY Violations**: Any repeated logic that should be extracted into shared utilities?
14+
- **Cognitive Load**: Can a new developer understand this change with less cognitive load?
15+
- **Magic Numbers/Strings**: All constants properly defined and named in @application_sdk/constants.py
16+
- **Spell Check**: No typos in code, comments, docstrings, or documentation
17+
- **Exception Handling Standards**: All exception handling must follow these principles. See detailed guidelines in [exception-handling.mdc](mdc:.cursor/rules/exception-handling.mdc).
18+
19+
### 🏗️ Architecture & Design
20+
21+
- **Module Boundaries**: Changes respect existing module responsibilities
22+
- **Error Handling**: Proper exception handling with meaningful error messages
23+
- **Resource Management**: Files, connections, and resources properly closed/released
24+
- **Async Patterns**: Proper async/await usage where applicable
25+
- **Configuration**: No hardcoded values; use proper configuration management
26+
27+
### 📝 Documentation Requirements
28+
29+
- **Docstrings**: All public functions, classes, and modules have Google-style docstrings
30+
- **Type Hints**: All function parameters and return values are typed
31+
- **Complex Logic**: Non-obvious business logic has inline comments explaining "why"
32+
33+
### 🧪 Testing
34+
35+
- **Testing Standards**: Testing standards are defined in [testing.mdc](mdc:.cursor/rules/testing.mdc)
36+
- **Test Coverage**: New code has corresponding tests (unit/integration/e2e as appropriate)
37+
- **Edge Cases**: Error conditions and boundary cases are tested
38+
- **Mock Strategy**: External dependencies properly mocked/isolated
39+
- **Test Naming**: Test names clearly describe the scenario being tested
40+
41+
### 🔒 Security & Performance
42+
43+
- **Input Validation**: All external inputs validated and sanitized
44+
- **Secrets Management**: No secrets in code; proper credential handling
45+
- **SQL Injection**: Parameterized queries used for all SQL operations
46+
- **Performance Standards**: All performance considerations must follow these principles. See detailed guidelines in [performance.mdc](mdc:.cursor/rules/performance.mdc).
47+
- **Memory Management**: Resources properly closed, large datasets processed in chunks
48+
- **DataFrame Optimization**: Appropriate dtypes, avoid unnecessary copies, use chunked processing
49+
- **SQL Query Efficiency**: Use LIMIT, specific columns, proper WHERE clauses, connection pooling
50+
- **Serialization Performance**: Use orjson for large datasets, implement compression
51+
- **Algorithm Efficiency**: Use appropriate data structures, avoid O(n²) when O(n) alternatives exist
52+
- **Caching Strategy**: Cache expensive operations and database queries
53+
- **Async Usage**: Use async for I/O operations, sync for CPU-bound tasks
54+
55+
### 📊 Observability & Logging
56+
57+
- **Logging Standards**: logging standards are defined in [logging.mdc](mdc:.cursor/rules/logging.mdc)
58+
- **Metrics**: Key operations include appropriate metrics
59+
- **Error Context**: Error logs include sufficient context for debugging
60+
- **Trace Information**: Critical paths include trace information
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
alwaysApply: false
3+
globs: application_sdk/**/*.py
4+
---
5+
# Exception Handling Standards
6+
7+
## Core Principles
8+
9+
**Default Behavior: Re-raise Exceptions** - Exceptions should be re-raised by default unless explicitly handled for a specific reason. Silent exception swallowing is not allowed.
10+
11+
## Critical Rules
12+
13+
### **Exception Propagation**
14+
- **Rule**: Always re-raise exceptions after logging unless in non-critical operations
15+
- **Anti-pattern**: `except Exception as e: logger.error(f"Error: {e}")` - This swallows exceptions
16+
- **Correct pattern**: `except Exception as e: logger.error(f"Error: {e}"); raise`
17+
18+
### **Specific Exception Types**
19+
- **Use specific exception types** instead of generic `Exception`
20+
- **Examples**: `ValueError`, `ConnectionError`, `TimeoutError`, `FileNotFoundError`
21+
- **Create custom exceptions** in `application_sdk/common/error_codes.py` for domain-specific errors
22+
- **Anti-pattern**: `except Exception:` - Too broad, masks real issues
23+
24+
## Exception Handling Patterns
25+
26+
### **✅ DO: Proper exception handling with re-raising**
27+
```python
28+
try:
29+
result = some_operation()
30+
return result
31+
except ValueError as e:
32+
logger.error(f"Invalid input: {e}")
33+
raise # Re-raise to propagate the error
34+
except ConnectionError as e:
35+
logger.error(f"Connection failed: {e}")
36+
raise # Re-raise to propagate the error
37+
except Exception as e:
38+
logger.error(f"Unexpected error: {e}")
39+
raise # Re-raise to propagate the error
40+
```
41+
42+
### **❌ DON'T: Swallowing exceptions**
43+
```python
44+
try:
45+
result = some_operation()
46+
return result
47+
except Exception as e:
48+
logger.error(f"Error: {e}")
49+
# Missing raise - this swallows the exception!
50+
```
51+
52+
## Context-Specific Guidelines
53+
54+
### **1. Critical Operations (Database, Network, File I/O)**
55+
- **Always re-raise** exceptions after logging
56+
- **Include context** in error messages
57+
- **Use specific exception types**
58+
59+
### **2. Non-Critical Operations (Logging, Metrics, Observability)**
60+
- **May swallow exceptions** to prevent cascading failures
61+
- **Log the failure** for debugging
62+
- **Continue operation** if possible
63+
64+
### **3. Resource Cleanup**
65+
- **Use try/finally** for guaranteed cleanup
66+
- **Log cleanup failures** but don't re-raise (to avoid masking original error)
67+
68+
## Common Anti-patterns to Reject
69+
70+
### **❌ Silent Exception Swallowing**
71+
```python
72+
try:
73+
operation()
74+
except Exception:
75+
pass # REJECT: Silent failure
76+
```
77+
78+
### **❌ Generic Exception Catching Without Re-raising**
79+
```python
80+
try:
81+
operation()
82+
except Exception as e:
83+
logger.error(f"Error: {e}") # REJECT: Swallows exception
84+
```
85+
86+
### **❌ Overly Broad Exception Handling**
87+
```python
88+
try:
89+
operation()
90+
except Exception as e: # REJECT: Too broad
91+
logger.error(f"Error: {e}")
92+
raise
93+
```
94+
95+
### **❌ Exception Handling Without Context**
96+
```python
97+
try:
98+
operation()
99+
except Exception as e:
100+
logger.error(f"Error: {e}") # REJECT: No context about what failed
101+
raise
102+
```
103+
104+
## Best Practices
105+
106+
### **✅ DO: Proper exception handling with context**
107+
```python
108+
try:
109+
result = database_connection.execute_query(query)
110+
return result
111+
except ConnectionError as e:
112+
logger.error(f"Database connection failed for query {query[:50]}...: {e}")
113+
raise
114+
except ValueError as e:
115+
logger.error(f"Invalid query parameters: {e}")
116+
raise
117+
except Exception as e:
118+
logger.error(f"Unexpected error during database operation: {e}")
119+
raise
120+
```
121+
122+
### **✅ DO: Resource cleanup with exception handling**
123+
```python
124+
file_handle = None
125+
try:
126+
file_handle = open(filename, 'r')
127+
return file_handle.read()
128+
except FileNotFoundError as e:
129+
logger.error(f"File not found: {filename}")
130+
raise
131+
finally:
132+
if file_handle:
133+
try:
134+
file_handle.close()
135+
except Exception as e:
136+
logger.warning(f"Failed to close file {filename}: {e}")
137+
# Don't re-raise cleanup errors
138+
```
139+
140+
### **✅ DO: Non-critical operation exception handling**
141+
```python
142+
try:
143+
metrics.record_metric("operation_success", 1)
144+
except Exception as e:
145+
logger.warning(f"Failed to record metric: {e}")
146+
# Don't re-raise for non-critical operations
147+
```
148+
149+
## Module-Specific Guidelines
150+
151+
### **Handlers (`application_sdk/handlers/`)**
152+
- **Critical**: Always re-raise exceptions after logging
153+
- **Include operation context** in error messages
154+
- **Use specific exception types** for different error scenarios
155+
156+
### **Outputs (`application_sdk/outputs/`)**
157+
- **Critical**: Re-raise exceptions for data writing operations
158+
- **Non-critical**: May swallow exceptions for metrics/logging operations
159+
- **Resource cleanup**: Ensure files/connections are properly closed
160+
161+
### **Inputs (`application_sdk/inputs/`)**
162+
- **Critical**: Re-raise exceptions for data reading operations
163+
- **Include file/connection context** in error messages
164+
- **Handle specific I/O exceptions** appropriately
165+
166+
### **Observability (`application_sdk/observability/`)**
167+
- **Non-critical**: May swallow exceptions to prevent cascading failures
168+
- **Log all failures** for debugging
169+
- **Continue operation** when possible
170+
171+
### **Workflows (`application_sdk/workflows/`)**
172+
- **Critical**: Re-raise exceptions to trigger workflow retry logic
173+
- **Include workflow context** in error messages
174+
- **Handle Temporal-specific exceptions** appropriately
175+
176+
### **Server (`application_sdk/server/`)**
177+
- **Critical**: Re-raise exceptions to return proper HTTP error responses
178+
- **Include request context** in error messages
179+
- **Handle HTTP-specific exceptions** appropriately
180+
181+
## Review Checklist
182+
183+
When reviewing code, check for:
184+
185+
1. **Exception Propagation**: Are exceptions properly re-raised when they should be?
186+
2. **Specific Exception Types**: Are specific exception types used instead of generic `Exception`?
187+
3. **Error Context**: Do error messages include sufficient context for debugging?
188+
4. **Resource Cleanup**: Are resources properly cleaned up in finally blocks?
189+
5. **Non-Critical Operations**: Are non-critical operations (logging, metrics) handled appropriately?
190+
6. **Custom Exceptions**: Are domain-specific exceptions defined in `error_codes.py`?
191+
7. **Exception Documentation**: Are exceptions documented in function docstrings?
192+
193+
## Implementation Notes
194+
195+
- **Custom Exceptions**: Define domain-specific exceptions in `application_sdk/common/error_codes.py`
196+
- **Logging**: Use `AtlanLoggerAdapter` for all logging with proper context
197+
- **Context**: Always include relevant context in error messages (query, filename, operation, etc.)
198+
- **Documentation**: Document all exceptions that functions can raise in docstrings

0 commit comments

Comments
 (0)