Skip to content

Commit f3d2bd4

Browse files
committed
feat: improve error handling in pdodb dump command
- Add typo detection for 'restore' command (suggests correct command) - Add table existence check before dumping (prevents fatal errors) - Improve exception handling with try/catch for QueryException and general Exception (replaces fatal errors with user-friendly messages) - Add tests for error handling: - testDumpCommandTypoInRestore() - verifies typo detection - testDumpCommandNonExistentTable() - verifies table existence check - All errors now display clear messages instead of fatal exceptions
1 parent 45da48e commit f3d2bd4

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/cli/commands/DumpCommand.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use tommyknocker\pdodb\cli\Command;
88
use tommyknocker\pdodb\cli\DumpManager;
9+
use tommyknocker\pdodb\exceptions\QueryException;
910
use tommyknocker\pdodb\exceptions\ResourceException;
1011

1112
/**
@@ -45,6 +46,11 @@ public function execute(): int
4546
return $this->restore();
4647
}
4748

49+
// Check for common typos in 'restore' command
50+
if ($firstArg !== null && (str_starts_with($firstArg, 'restor') || str_starts_with($firstArg, 'retor'))) {
51+
return $this->showError("Unknown command: '{$firstArg}'. Did you mean 'restore'?");
52+
}
53+
4854
// If no arguments, check if dump-specific options are provided
4955
// If yes, dump entire database; if no, show help
5056
if ($firstArg === null) {
@@ -80,6 +86,15 @@ protected function dump(): int
8086

8187
try {
8288
$db = $this->getDb();
89+
90+
// Check if table exists when table name is provided
91+
if (is_string($table) && $table !== '') {
92+
$schema = $db->schema();
93+
if (!$schema->tableExists($table)) {
94+
return $this->showError("Table '{$table}' does not exist");
95+
}
96+
}
97+
8398
$sql = DumpManager::dump($db, is_string($table) ? $table : null, $schemaOnly, $dataOnly, $dropTables);
8499

85100
if (is_string($output) && $output !== '') {
@@ -95,6 +110,15 @@ protected function dump(): int
95110
return 0;
96111
} catch (ResourceException $e) {
97112
return $this->showError($e->getMessage());
113+
} catch (QueryException $e) {
114+
// Check if error is about table not found
115+
$message = $e->getMessage();
116+
if (is_string($table) && $table !== '' && (str_contains($message, "doesn't exist") || str_contains($message, 'not found'))) {
117+
return $this->showError("Table '{$table}' does not exist");
118+
}
119+
return $this->showError($message);
120+
} catch (\Exception $e) {
121+
return $this->showError($e->getMessage());
98122
}
99123
}
100124

tests/shared/DumpCommandCliTests.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,27 @@ public function testDumpCommandNoDropTablesOption(): void
212212

213213
unlink($dumpFile);
214214
}
215+
216+
public function testDumpCommandTypoInRestore(): void
217+
{
218+
// Run in a subprocess to avoid exit() killing PHPUnit
219+
$bin = realpath(__DIR__ . '/../../bin/pdodb');
220+
$env = 'PDODB_DRIVER=sqlite PDODB_PATH=' . escapeshellarg(self::$dbPath) . ' PDODB_NON_INTERACTIVE=1';
221+
$cmd = $env . ' ' . escapeshellcmd(PHP_BINARY) . ' ' . escapeshellarg((string)$bin) . ' dump retore 2>&1';
222+
$out = (string)shell_exec($cmd);
223+
$this->assertStringContainsString('Error:', $out);
224+
$this->assertStringContainsString("Unknown command: 'retore'", $out);
225+
$this->assertStringContainsString("Did you mean 'restore'?", $out);
226+
}
227+
228+
public function testDumpCommandNonExistentTable(): void
229+
{
230+
// Run in a subprocess to avoid exit() killing PHPUnit
231+
$bin = realpath(__DIR__ . '/../../bin/pdodb');
232+
$env = 'PDODB_DRIVER=sqlite PDODB_PATH=' . escapeshellarg(self::$dbPath) . ' PDODB_NON_INTERACTIVE=1';
233+
$cmd = $env . ' ' . escapeshellcmd(PHP_BINARY) . ' ' . escapeshellarg((string)$bin) . ' dump nonexistent_table 2>&1';
234+
$out = (string)shell_exec($cmd);
235+
$this->assertStringContainsString('Error:', $out);
236+
$this->assertStringContainsString("Table 'nonexistent_table' does not exist", $out);
237+
}
215238
}

0 commit comments

Comments
 (0)