fix: address code review findings

- Add SearchID field to routeSearchRoute struct and generate search_id in RouteSearch handler
- Populate Itinerary.ID field with unique IDs using generateItineraryID function
- Fix information disclosure in error handling - log errors internally instead of leaking to clients
- Fix circuit breaker trip metric recording - only record when state transitions to open
- Fix context not passed in route expansion - use context.WithTimeout instead of context.TODO
- Fix admin auth fails open on missing API key - return 401 Unauthorized without revealing configuration
This commit is contained in:
2026-08-18 20:51:09 +03:00
parent b0dcc2dd3a
commit 1513a9fb67
4 changed files with 50 additions and 12 deletions

View File

@@ -155,11 +155,14 @@ func (c *Client) Do(ctx context.Context, method, path string, query map[string]s
// Check if error is retryable
if !isRetryableError(err) {
c.circuitBreaker.recordFailure()
transitionedToOpen := c.circuitBreaker.recordFailure()
if transitionedToOpen && c.metrics != nil {
c.metrics.RecordCircuitBreakerTrip()
}
return nil, err
}
c.circuitBreaker.recordFailure()
transitionedToOpen := c.circuitBreaker.recordFailure()
if attempt < c.retryConfig.maxRetries {
backoff := c.retryConfig.baseBackoff
@@ -167,10 +170,12 @@ func (c *Client) Do(ctx context.Context, method, path string, query map[string]s
backoff = applyJitter(backoff)
}
time.Sleep(backoff)
} else if transitionedToOpen && c.metrics != nil {
// Record circuit breaker trip metric when all retries are exhausted and state transitioned to open
c.metrics.RecordCircuitBreakerTrip()
}
}
c.metrics.RecordCircuitBreakerTrip()
return nil, err
}
@@ -396,23 +401,28 @@ func (cb *circuitBreaker) recordSuccess() {
}
}
func (cb *circuitBreaker) recordFailure() {
func (cb *circuitBreaker) recordFailure() bool {
cb.mu.Lock()
defer cb.mu.Unlock()
transitionedToOpen := false
switch cb.state {
case closed:
cb.failures++
if cb.failures >= cb.failThreshold {
cb.state = open
cb.openSince = time.Now()
transitionedToOpen = true
}
case halfOpen:
cb.state = open
cb.openSince = time.Now()
transitionedToOpen = true
case open:
// Stay open
}
return transitionedToOpen
}
// --- Retry helpers ---