fix: rTorrent null-safety, configurable SAB_HISTORY_LIMIT, lastError visibility (#68)
Build and Push Docker Image / build (push) Successful in 59s
Docs Check / Markdown lint (push) Failing after 1m45s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 2m7s
CI / Security audit (push) Successful in 2m33s
Docs Check / Mermaid diagram parse check (push) Successful in 2m55s
CI / Swagger Validation & Coverage (push) Successful in 3m19s
CI / Tests & coverage (push) Successful in 3m29s

- RTorrentClient: guard d.multicall2 returning non-array, per-row try/catch,
  explicit Number()/String() coercions, _extractArrInfo null-safe
- RTorrentClient.getClientStatus: coerce rates through Number.isFinite
- SABnzbdClient: history limit now reads SAB_HISTORY_LIMIT env var (default 10)
- DownloadClient: added _recordLastError, _clearLastError, getLastError on base
- All four clients call _recordLastError on failure, _clearLastError on success
- DownloadClientRegistry.getAllClientStatuses: includes lastError in result
- GET /api/status/status: exposes downloadClients[] array with per-client lastError
- Tests: RTorrentClient null-safety + lastError, SABnzbd history limit + lastError,
  downloadClients.test expectation updated for new lastError field
This commit is contained in:
2026-05-28 16:22:11 +01:00
parent 3d49c926dc
commit 6fa9c79a7d
11 changed files with 284 additions and 22 deletions
+6 -1
View File
@@ -18,9 +18,11 @@ class TransmissionClient extends DownloadClient {
try {
await this.makeRequest('session-get');
logToFile(`[Transmission:${this.name}] Connection test successful`);
this._clearLastError();
return true;
} catch (error) {
logToFile(`[Transmission:${this.name}] Connection test failed: ${error.message}`);
this._recordLastError('testConnection', error);
return false;
}
}
@@ -80,10 +82,11 @@ class TransmissionClient extends DownloadClient {
const torrents = response.data.arguments.torrents || [];
logToFile(`[Transmission:${this.name}] Retrieved ${torrents.length} torrents`);
this._clearLastError();
return torrents.map(torrent => this.normalizeDownload(torrent));
} catch (error) {
logToFile(`[Transmission:${this.name}] Error fetching torrents: ${error.message}`);
this._recordLastError('getActiveDownloads', error);
return [];
}
}
@@ -93,12 +96,14 @@ class TransmissionClient extends DownloadClient {
const response = await this.makeRequest('session-get');
const sessionStats = await this.makeRequest('session-stats');
this._clearLastError();
return {
session: response.data.arguments,
stats: sessionStats.data.arguments
};
} catch (error) {
logToFile(`[Transmission:${this.name}] Error getting client status: ${error.message}`);
this._recordLastError('getClientStatus', error);
return null;
}
}