-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Backend 500 Error: Contact List API
Issue Type: Bug
Priority: High
Component: Backend API
Related Task: #170 (Contact Management Screens Migration)
Description
The GET /rest/contact/getContactList endpoint returns a 500 Internal Server Error with an empty response body. This is blocking Task #170 (Contact Management Screens Migration).
Error Details
Endpoint: GET /rest/contact/getContactList?pageNo=0&pageSize=10&paginationDisable=false
Status Code: 500
Response Body: Empty (no JSON response)
Headers: Standard HTTP headers, no error details in response
Reproduction Steps
- Start backend:
docker compose -f deploy/docker/docker-compose.yml up -d backend - Wait for backend to start (35 seconds)
- Get authentication token:
TOKEN=$(curl -s -X POST http://localhost:8080/auth/token \ -H "Content-Type: application/json" \ -d '{"username":"test@example.com","password":"Test@1234"}' \ | python3 -c "import sys, json; print(json.load(sys.stdin)['token'])")
- Call the endpoint:
curl -X GET "http://localhost:8080/rest/contact/getContactList?pageNo=0&pageSize=10&paginationDisable=false" \ -H "Authorization: Bearer $TOKEN"
- Expected: JSON response with contact list
Actual: 500 error with empty response body
Investigation Summary
What Was Tested
- Test Endpoint Works:
/rest/contact/testContactList(returns emptyPaginationResponseModel) - ✅ Works - Product Endpoint Works:
/rest/product/getList(similar structure) - ✅ Works - Contact Endpoint Fails:
/rest/contact/getContactList- ❌ 500 error
Code Structure
The ContactController.getContactList method follows the same pattern as ProductRestController.getProductList:
- Both use
@LogRequestannotation - Both return
ResponseEntity<PaginationResponseModel> - Both convert entities to models using helper classes
- Both use the same
PaginationResponseModelstructure
Attempted Fixes (All Reverted)
- ✅ Removed
@AllArgsConstructorfromContactListModel(matchedProductListModel) - ✅ Added
@JsonIgnoreto unused fields (nextDueDate,dueAmount,exchangeRate) - ✅ Ensured
totalRecordsis set correctly inPaginationResponseModel - ✅ Added null checks and defensive coding
- ✅ Simplified code to match
ProductRestControllerexactly - ✅ Tested with minimal
ContactListModel(only basic fields) - ✅ Disabled
@LogRequestaspect temporarily - ✅ Added extensive logging (no logs appeared in Docker output)
Key Observations
- Hibernate queries execute: Service layer is called successfully
- No exceptions in logs: No error messages appear in backend logs
- Empty response: 500 error with no response body suggests serialization failure
- Test endpoint works: Empty
PaginationResponseModelserializes correctly - Product endpoint works: Similar structure works fine
Hypothesis
The error likely occurs during Spring's response serialization after the method returns successfully. Possible causes:
- Serialization Issue:
ContactListModelorContactHelper.getModel()creates objects that can't be serialized - Lazy Loading Exception: Hibernate lazy-loaded associations accessed outside transaction
- Circular Reference: Jackson serialization encounters circular reference
- Type Mismatch: Database field types don't match model field types
Environment
- Backend: Spring Boot 3.4.1
- Database: PostgreSQL 14+
- Java: 21
- Container: Docker Compose
- Build:
docker compose -f deploy/docker/docker-compose.yml build backend --no-cache
Related Files
apps/backend/src/main/java/com/simpleaccounts/rest/contactcontroller/ContactController.javaapps/backend/src/main/java/com/simpleaccounts/rest/contactcontroller/ContactHelper.javaapps/backend/src/main/java/com/simpleaccounts/rest/contactcontroller/ContactListModel.javaapps/backend/src/main/java/com/simpleaccounts/rest/PaginationResponseModel.javaapps/backend/src/main/java/com/simpleaccounts/entity/Contact.java
Comparison with Working Endpoint
ProductRestController.getProductList (✅ Works):
@LogRequest
@GetMapping(value = "/getList")
public ResponseEntity<PaginationResponseModel> getProductList(...) {
// Same structure as ContactController
// Returns successfully
}ContactController.getContactList (❌ Fails):
@LogRequest
@GetMapping(value = "/getContactList")
public ResponseEntity<PaginationResponseModel> getContactList(...) {
// Same structure as ProductRestController
// Returns 500 error
}Next Steps
- Enable detailed logging in Spring Boot to capture serialization errors
- Check database schema for type mismatches
- Test with minimal contact (single record with minimal fields)
- Compare
ContactHelper.getModel()withProductRestHelper.getListModel() - Check for lazy-loaded associations that might cause
LazyInitializationException - Review Jackson configuration for custom serializers/deserializers
Impact
- Blocks: Task [TASK] Migrate Contact management screens #170 (Contact Management Screens Migration)
- Affects: Contact list functionality in frontend
- Workaround: None available - endpoint must be fixed
Additional Notes
- All debugging instrumentation has been removed
- Code structure matches working
ProductRestController - No compilation errors
- Backend builds successfully
- Issue persists even with minimal data