mirror of
https://github.com/HabiRabbu/Musicseerr
synced 2026-04-21 13:37:27 +00:00
fix - count circuit breaker failures per logical call NOT per retry + actionable errors and placeholder in lidarr connection test
This commit is contained in:
parent
d65e1a7971
commit
491947ecab
4 changed files with 24 additions and 9 deletions
|
|
@ -244,10 +244,6 @@ def with_retry(
|
|||
last_exception = e
|
||||
elapsed_ms = int((time.time() - attempt_start) * 1000)
|
||||
|
||||
is_non_breaking = isinstance(e, non_breaking_exceptions) if non_breaking_exceptions else False
|
||||
if circuit_breaker and (not is_non_breaking or circuit_breaker.state == CircuitState.HALF_OPEN):
|
||||
await circuit_breaker.arecord_failure()
|
||||
|
||||
if attempt >= max_attempts:
|
||||
total_elapsed_ms = int((time.time() - start_time) * 1000)
|
||||
logger.error(
|
||||
|
|
@ -295,6 +291,11 @@ def with_retry(
|
|||
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
if circuit_breaker and last_exception:
|
||||
is_non_breaking = isinstance(last_exception, non_breaking_exceptions) if non_breaking_exceptions else False
|
||||
if not is_non_breaking or circuit_breaker.state == CircuitState.HALF_OPEN:
|
||||
await circuit_breaker.arecord_failure()
|
||||
|
||||
raise last_exception
|
||||
|
||||
return wrapper
|
||||
|
|
|
|||
|
|
@ -132,10 +132,19 @@ class SettingsService:
|
|||
root_folders=root_folders
|
||||
)
|
||||
except ExternalServiceError as e:
|
||||
logger.warning(f"Lidarr connection test failed: {e}")
|
||||
detail = str(e)
|
||||
logger.warning(f"Lidarr connection test failed: {detail}")
|
||||
if "No address associated with hostname" in detail or "Name or service not known" in detail:
|
||||
hint = "DNS resolution failed — check the hostname is reachable from inside the container"
|
||||
elif "Connection refused" in detail:
|
||||
hint = "Connection refused — check the port and that Lidarr is running"
|
||||
elif "timed out" in detail.lower() or "timeout" in detail.lower():
|
||||
hint = "Connection timed out — check network/firewall settings"
|
||||
else:
|
||||
hint = detail
|
||||
return LidarrVerifyResponse(
|
||||
success=False,
|
||||
message="Couldn't reach Lidarr",
|
||||
message=f"Couldn't reach Lidarr: {hint}",
|
||||
quality_profiles=[],
|
||||
metadata_profiles=[],
|
||||
root_folders=[]
|
||||
|
|
@ -144,7 +153,7 @@ class SettingsService:
|
|||
logger.exception(f"Failed to verify Lidarr connection: {e}")
|
||||
return LidarrVerifyResponse(
|
||||
success=False,
|
||||
message="Couldn't finish the connection test",
|
||||
message=f"Couldn't finish the connection test: {e}",
|
||||
quality_profiles=[],
|
||||
metadata_profiles=[],
|
||||
root_folders=[]
|
||||
|
|
|
|||
|
|
@ -68,10 +68,15 @@ async def test_breaking_exception_still_trips_circuit():
|
|||
call_count += 1
|
||||
raise _ServiceDown("down")
|
||||
|
||||
# Each call records one failure after all retries exhausted (not per retry)
|
||||
with pytest.raises(_ServiceDown):
|
||||
await fail()
|
||||
assert cb.failure_count == 1
|
||||
assert cb.state == CircuitState.CLOSED
|
||||
|
||||
assert call_count == 3
|
||||
call_count = 0
|
||||
with pytest.raises(_ServiceDown):
|
||||
await fail()
|
||||
assert cb.state == CircuitState.OPEN
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
type="url"
|
||||
bind:value={form.data.lidarr_url}
|
||||
class="input input-bordered w-full"
|
||||
placeholder="http://localhost:8686"
|
||||
placeholder="http://lidarr:8686 or http://<host-ip>:8686"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue