Problem
Requests to GET /api/cards/compare are incorrectly matched by the @GetMapping("/{id}") endpoint in CreditCardController, causing a MethodArgumentTypeMismatchException when Spring attempts to convert the string "compare" to java.lang.Long. This results in HTTP 400 Bad Request errors and breaks the card comparison feature.
Evidence
Production logs (2026-04-25 ~00:01 UTC) — 3 occurrences within 10 seconds:
WARN DefaultHandlerExceptionResolver: Resolved [MethodArgumentTypeMismatchException:
Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long';
For input string: "compare"]
Detected by automated health check on ca-banking-demo-backend (revision ca-banking-demo-backend--azd-1774558182).
Root Cause
CreditCardController maps @GetMapping("/{id}") which acts as a catch-all for any path under /api/cards/. When /api/cards/compare is requested, Spring matches it to /{id} and fails the type conversion from String to Long.
Affected file: backend/src/main/java/com/threeriversbank/controller/CreditCardController.java (line 42)
Fix (Ready on branch fix/cards-compare-routing-bug)
1. New /compare endpoint (CreditCardController.java)
Add @GetMapping("/compare") mapped before /{id} to prevent route ambiguity. Accepts optional ids query parameter for targeted comparison:
@GetMapping("/compare")
@Operation(summary = "Compare credit cards")
public ResponseEntity<List<CreditCardDto>> compareCards(
@RequestParam(required = false) List<Long> ids) {
List<CreditCardDto> cards;
if (ids != null && !ids.isEmpty()) {
cards = creditCardService.getCardsByIds(ids);
} else {
cards = creditCardService.getAllCreditCards();
}
return ResponseEntity.ok(cards);
}
2. New service method (CreditCardService.java)
@Transactional(readOnly = true)
public List<CreditCardDto> getCardsByIds(List<Long> ids) {
return creditCardRepository.findAllById(ids).stream()
.map(this::convertToDtoWithDetails)
.collect(Collectors.toList());
}
3. Global Exception Handler (GlobalExceptionHandler.java)
New @RestControllerAdvice class that handles MethodArgumentTypeMismatchException and RuntimeException with structured JSON error responses.
4. Unit tests (CreditCardControllerTest.java)
compareCards_WithIds_ShouldReturnSelectedCards
compareCards_WithoutIds_ShouldReturnAllCards
Impact
- Severity: Medium — card comparison feature is broken for users navigating to
/api/cards/compare
- Scope: Backend only; frontend comparison page (
/cards) works via GET /api/cards but direct API access fails
This issue was created by sre-sre-three-rivers-bswqe--b2b14894
Tracked by the SRE agent here
Problem
Requests to
GET /api/cards/compareare incorrectly matched by the@GetMapping("/{id}")endpoint inCreditCardController, causing aMethodArgumentTypeMismatchExceptionwhen Spring attempts to convert the string"compare"tojava.lang.Long. This results in HTTP 400 Bad Request errors and breaks the card comparison feature.Evidence
Production logs (2026-04-25 ~00:01 UTC) — 3 occurrences within 10 seconds:
Detected by automated health check on
ca-banking-demo-backend(revisionca-banking-demo-backend--azd-1774558182).Root Cause
CreditCardControllermaps@GetMapping("/{id}")which acts as a catch-all for any path under/api/cards/. When/api/cards/compareis requested, Spring matches it to/{id}and fails the type conversion fromStringtoLong.Affected file:
backend/src/main/java/com/threeriversbank/controller/CreditCardController.java(line 42)Fix (Ready on branch
fix/cards-compare-routing-bug)1. New
/compareendpoint (CreditCardController.java)Add
@GetMapping("/compare")mapped before/{id}to prevent route ambiguity. Accepts optionalidsquery parameter for targeted comparison:2. New service method (
CreditCardService.java)3. Global Exception Handler (
GlobalExceptionHandler.java)New
@RestControllerAdviceclass that handlesMethodArgumentTypeMismatchExceptionandRuntimeExceptionwith structured JSON error responses.4. Unit tests (
CreditCardControllerTest.java)compareCards_WithIds_ShouldReturnSelectedCardscompareCards_WithoutIds_ShouldReturnAllCardsImpact
/api/cards/compare/cards) works viaGET /api/cardsbut direct API access failsThis issue was created by sre-sre-three-rivers-bswqe--b2b14894
Tracked by the SRE agent here