mirror of
https://github.com/unraid/api.git
synced 2026-01-01 06:01:18 -06:00
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 -->
This commit is contained in:
@@ -37,8 +37,23 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
|||||||
process.env.RCLONE_PASSWORD || crypto.randomBytes(24).toString('base64');
|
process.env.RCLONE_PASSWORD || crypto.randomBytes(24).toString('base64');
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the RClone service is initialized and ready to use
|
||||||
|
*/
|
||||||
|
get initialized(): boolean {
|
||||||
|
return this.isInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
async onModuleInit(): Promise<void> {
|
async onModuleInit(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
// Check if rclone binary is available first
|
||||||
|
const isBinaryAvailable = await this.checkRcloneBinaryExists();
|
||||||
|
if (!isBinaryAvailable) {
|
||||||
|
this.logger.warn('RClone binary not found on system, skipping initialization');
|
||||||
|
this.isInitialized = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { getters } = await import('@app/store/index.js');
|
const { getters } = await import('@app/store/index.js');
|
||||||
// Check if Rclone Socket is running, if not, start it.
|
// Check if Rclone Socket is running, if not, start it.
|
||||||
this.rcloneSocketPath = getters.paths()['rclone-socket'];
|
this.rcloneSocketPath = getters.paths()['rclone-socket'];
|
||||||
@@ -198,16 +213,38 @@ export class RCloneApiService implements OnModuleInit, OnModuleDestroy {
|
|||||||
* Checks if the RClone socket is running
|
* Checks if the RClone socket is running
|
||||||
*/
|
*/
|
||||||
private async checkRcloneSocketRunning(): Promise<boolean> {
|
private async checkRcloneSocketRunning(): Promise<boolean> {
|
||||||
// Use the API check instead of execa('rclone', ['about']) as rclone might not be in PATH
|
|
||||||
// or configured correctly for the execa environment vs the rcd environment.
|
|
||||||
try {
|
try {
|
||||||
// A simple API call to check if the daemon is responsive
|
// A simple API call to check if the daemon is responsive
|
||||||
await this.callRcloneApi('core/pid');
|
await this.callRcloneApi('core/pid');
|
||||||
this.logger.debug('RClone socket is running and responsive.');
|
this.logger.debug('RClone socket is running and responsive.');
|
||||||
return true;
|
return true;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
// Log less verbosely during checks
|
// Silently handle socket connection errors during checks
|
||||||
// this.logger.error(`Error checking RClone socket: ${error}`);
|
if (error instanceof Error) {
|
||||||
|
if (error.message.includes('ENOENT') || error.message.includes('ECONNREFUSED')) {
|
||||||
|
this.logger.debug('RClone socket not accessible - daemon likely not running');
|
||||||
|
} else {
|
||||||
|
this.logger.debug(`RClone socket check failed: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the RClone binary is available on the system
|
||||||
|
*/
|
||||||
|
private async checkRcloneBinaryExists(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await execa('rclone', ['version']);
|
||||||
|
this.logger.debug('RClone binary is available on the system.');
|
||||||
|
return true;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
||||||
|
this.logger.warn('RClone binary not found in PATH.');
|
||||||
|
} else {
|
||||||
|
this.logger.error(`Error checking RClone binary: ${error}`);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,13 @@ export class RCloneService {
|
|||||||
*/
|
*/
|
||||||
async onModuleInit(): Promise<void> {
|
async onModuleInit(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await this.loadProviderInfo();
|
if (!this.rcloneApiService.initialized) {
|
||||||
|
this.logger.warn(
|
||||||
|
'RClone API service is not initialized, skipping provider info loading'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await this.loadProviderInfo();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(`Failed to initialize RcloneBackupSettingsService: ${error}`);
|
this.logger.error(`Failed to initialize RcloneBackupSettingsService: ${error}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user