fix(utils): handle file write failures with rollback
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 5s

- Add error handling and rollback logic for unit file writes
- Prevent partial file writes by removing created files on failure
- Update tests to reflect new return type and error handling
This commit is contained in:
2025-05-21 09:51:16 +02:00
parent a76417ce1d
commit bd71b8ee14
3 changed files with 30 additions and 8 deletions

View File

@@ -12,14 +12,20 @@ export async function generateUnitFiles(options: TimerOptions): Promise<void> {
console.log(`\n===== ${name}.timer =====`); console.log(`\n===== ${name}.timer =====`);
console.log(timerUnit); console.log(timerUnit);
} else { } else {
const { servicePath, timerPath } = await writeUnitFiles( const result = await writeUnitFiles(
name, name,
serviceUnit, serviceUnit,
timerUnit, timerUnit,
options, options,
); );
console.log(`Service unit written to: ${servicePath}`);
console.log(`Timer unit written to: ${timerPath}`); if (result) {
const { servicePath, timerPath } = result;
console.log(`Service Unit geschrieben in: ${servicePath}`);
console.log(`Timer Unit geschrieben in: ${timerPath}`);
} else {
return;
}
console.log(`\nℹ️ Hinweis:`); console.log(`\nℹ️ Hinweis:`);

View File

@@ -24,7 +24,7 @@ Deno.test('writeUnitFiles schreibt .service und .timer korrekt', async () => {
serviceContent, serviceContent,
timerContent, timerContent,
options as TimerOptions, options as TimerOptions,
); ) as { servicePath: string; timerPath: string };
// Überprüfe Pfade // Überprüfe Pfade
assertEquals(servicePath, join(tmp, 'test-backup.service')); assertEquals(servicePath, join(tmp, 'test-backup.service'));

View File

@@ -1,4 +1,4 @@
import { ensureDir } from 'https://deno.land/std@0.224.0/fs/mod.ts'; import { ensureDir, exists } from 'https://deno.land/std@0.224.0/fs/mod.ts';
import { join } from 'https://deno.land/std@0.224.0/path/mod.ts'; import { join } from 'https://deno.land/std@0.224.0/path/mod.ts';
import { TimerOptions } from '../types/mod.ts'; import { TimerOptions } from '../types/mod.ts';
@@ -7,7 +7,7 @@ export async function writeUnitFiles(
serviceContent: string, serviceContent: string,
timerContent: string, timerContent: string,
options: TimerOptions, options: TimerOptions,
): Promise<{ servicePath: string; timerPath: string }> { ): Promise<{ servicePath: string; timerPath: string } | undefined> {
const basePath = resolveUnitTargetPath(options); const basePath = resolveUnitTargetPath(options);
await ensureDir(basePath); await ensureDir(basePath);
@@ -15,8 +15,24 @@ export async function writeUnitFiles(
const servicePath = join(basePath, `${name}.service`); const servicePath = join(basePath, `${name}.service`);
const timerPath = join(basePath, `${name}.timer`); const timerPath = join(basePath, `${name}.timer`);
await Deno.writeTextFile(servicePath, serviceContent); try {
await Deno.writeTextFile(timerPath, timerContent); await Deno.writeTextFile(servicePath, serviceContent);
await Deno.writeTextFile(timerPath, timerContent);
} catch (error) {
// Rollback: Remove any files that were written
try {
if (await exists(servicePath)) {
await Deno.remove(servicePath);
}
if (await exists(timerPath)) {
await Deno.remove(timerPath);
}
} catch (rollbackError) {
console.error('Rollback fehlgeschlagen:', rollbackError);
}
console.error('Fehler beim Schreiben der Units:', error);
return undefined;
}
return { servicePath, timerPath }; return { servicePath, timerPath };
} }