Skip to content

Commit 7c6f02a

Browse files
authored
fix: allow rclone to fail to initialize (#1453)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a way for users to check if the RClone service is initialized. * **Bug Fixes** * Improved error handling and logging for RClone service initialization and connection checks, providing clearer and more informative messages if the RClone binary is missing or if connection issues occur. * Skipped loading provider information when the RClone service is not initialized, preventing unnecessary errors and warnings. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent ffb2ac5 commit 7c6f02a

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

api/src/unraid-api/graph/resolvers/rclone/rclone-api.service.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,23 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
3737
process.env.RCLONE_PASSWORD || crypto.randomBytes(24).toString('base64');
3838
constructor() {}
3939

40+
/**
41+
* Returns whether the RClone service is initialized and ready to use
42+
*/
43+
get initialized(): boolean {
44+
return this.isInitialized;
45+
}
46+
4047
async onModuleInit(): Promise<void> {
4148
try {
49+
// Check if rclone binary is available first
50+
const isBinaryAvailable = await this.checkRcloneBinaryExists();
51+
if (!isBinaryAvailable) {
52+
this.logger.warn('RClone binary not found on system, skipping initialization');
53+
this.isInitialized = false;
54+
return;
55+
}
56+
4257
const { getters } = await import('@app/store/index.js');
4358
// Check if Rclone Socket is running, if not, start it.
4459
this.rcloneSocketPath = getters.paths()['rclone-socket'];
@@ -198,16 +213,38 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
198213
* Checks if the RClone socket is running
199214
*/
200215
private async checkRcloneSocketRunning(): Promise<boolean> {
201-
// Use the API check instead of execa('rclone', ['about']) as rclone might not be in PATH
202-
// or configured correctly for the execa environment vs the rcd environment.
203216
try {
204217
// A simple API call to check if the daemon is responsive
205218
await this.callRcloneApi('core/pid');
206219
this.logger.debug('RClone socket is running and responsive.');
207220
return true;
208221
} catch (error: unknown) {
209-
// Log less verbosely during checks
210-
// this.logger.error(`Error checking RClone socket: ${error}`);
222+
// Silently handle socket connection errors during checks
223+
if (error instanceof Error) {
224+
if (error.message.includes('ENOENT') || error.message.includes('ECONNREFUSED')) {
225+
this.logger.debug('RClone socket not accessible - daemon likely not running');
226+
} else {
227+
this.logger.debug(`RClone socket check failed: ${error.message}`);
228+
}
229+
}
230+
return false;
231+
}
232+
}
233+
234+
/**
235+
* Checks if the RClone binary is available on the system
236+
*/
237+
private async checkRcloneBinaryExists(): Promise<boolean> {
238+
try {
239+
await execa('rclone', ['version']);
240+
this.logger.debug('RClone binary is available on the system.');
241+
return true;
242+
} catch (error: unknown) {
243+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
244+
this.logger.warn('RClone binary not found in PATH.');
245+
} else {
246+
this.logger.error(`Error checking RClone binary: ${error}`);
247+
}
211248
return false;
212249
}
213250
}

api/src/unraid-api/graph/resolvers/rclone/rclone.service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ export class RCloneService {
4848
*/
4949
async onModuleInit(): Promise<void> {
5050
try {
51-
await this.loadProviderInfo();
51+
if (!this.rcloneApiService.initialized) {
52+
this.logger.warn(
53+
'RClone API service is not initialized, skipping provider info loading'
54+
);
55+
} else {
56+
await this.loadProviderInfo();
57+
}
5258
} catch (error) {
5359
this.logger.error(`Failed to initialize RcloneBackupSettingsService: ${error}`);
5460
}

0 commit comments

Comments
 (0)