mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
Improve error message when passing a non-existent file to clickhouse
When running `clickhouse path/to/nonexistent.sql` or `clickhouse local /tmp/aaa.rep`, the error messages were confusing: the main binary showed the generic "Use one of the following commands" help, and `clickhouse-local` showed "Positional option is not supported". Now, if the argument looks like a file path (contains `/` or `.`) but the file doesn't exist, a clear "no such file" error is shown instead. Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
2ed123be11
commit
66aeef7f59
@@ -400,6 +400,26 @@ int main(int argc_, char ** argv_)
|
||||
main_func = mainEntryClickHouseLocal;
|
||||
}
|
||||
|
||||
/// If the argument looks like a file path but doesn't exist, provide a helpful error
|
||||
/// instead of the generic "Use one of the following commands" message.
|
||||
/// The check above routes existing files to clickhouse-local, but when the file
|
||||
/// doesn't exist, we fall through to `printHelpOnError` which is confusing:
|
||||
/// $ clickhouse tests/queries/0_stateless/my_test.sql
|
||||
/// Use one of the following commands: ...
|
||||
/// We detect file-like arguments by the presence of `/` (path separator)
|
||||
/// or `.` (file extension), which distinguishes them from mistyped subcommand
|
||||
/// names like "clickhouse sever" where the generic help is appropriate.
|
||||
if (main_func == printHelpOnError && argv.size() >= 2)
|
||||
{
|
||||
std::string_view arg(argv[1]);
|
||||
if (arg.contains('/') || arg.contains('.'))
|
||||
{
|
||||
std::cerr << "Error: no such file: " << arg << std::endl;
|
||||
std::cerr << "If you intended to run a script, please check the path." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int exit_code = main_func(static_cast<int>(argv.size()), argv.data());
|
||||
|
||||
#if defined(SANITIZE_COVERAGE)
|
||||
|
||||
@@ -71,6 +71,13 @@ void ClientApplicationBase::parseAndCheckOptions(OptionsDescription & options_de
|
||||
option = "query";
|
||||
else if (std::filesystem::is_regular_file(std::filesystem::path{token}, ec))
|
||||
option = "queries-file";
|
||||
else if (token.contains('/') || token.contains('.'))
|
||||
/// The argument looks like a file path (contains `/` or `.`) but doesn't exist on disk.
|
||||
/// Give a clear "no such file" error rather than the generic "positional option is not supported"
|
||||
/// which is confusing when the user meant to pass a file, e.g.:
|
||||
/// $ clickhouse local /tmp/aaa.rep
|
||||
/// Positional option `/tmp/aaa.rep` is not supported.
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "No such file: {}", token);
|
||||
else
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Error: no such file: /tmp/nonexistent_04001.sql
|
||||
If you intended to run a script, please check the path.
|
||||
exit: 1
|
||||
Error: no such file: nonexistent_04001.sql
|
||||
If you intended to run a script, please check the path.
|
||||
exit: 1
|
||||
No such file: /tmp/nonexistent_04001.sql
|
||||
No such file: nonexistent_04001.rep
|
||||
Use one of the following commands:
|
||||
OK_04001
|
||||
OK_04001
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
# When the argument to the main binary looks like a file path but doesn't exist,
|
||||
# the error message should say "no such file" instead of showing the generic help.
|
||||
|
||||
# Main binary with non-existent path containing a slash:
|
||||
${CLICKHOUSE_BINARY} /tmp/nonexistent_04001.sql 2>&1
|
||||
echo "exit: $?"
|
||||
|
||||
# Main binary with non-existent path containing a dot:
|
||||
${CLICKHOUSE_BINARY} nonexistent_04001.sql 2>&1
|
||||
echo "exit: $?"
|
||||
|
||||
# clickhouse-local with non-existent file path:
|
||||
${CLICKHOUSE_LOCAL} /tmp/nonexistent_04001.sql 2>&1 | grep -o 'No such file: /tmp/nonexistent_04001.sql'
|
||||
${CLICKHOUSE_LOCAL} nonexistent_04001.rep 2>&1 | grep -o 'No such file: nonexistent_04001.rep'
|
||||
|
||||
# A bare word without dots or slashes should still show the generic help:
|
||||
${CLICKHOUSE_BINARY} nonexistent_command 2>&1 | grep -F 'Use one of the following commands'
|
||||
|
||||
# Existing file should still work (routed to clickhouse-local):
|
||||
echo "SELECT 'OK_04001'" > /tmp/clickhouse_test_04001.sql
|
||||
${CLICKHOUSE_BINARY} /tmp/clickhouse_test_04001.sql 2>&1
|
||||
${CLICKHOUSE_LOCAL} /tmp/clickhouse_test_04001.sql 2>&1
|
||||
rm -f /tmp/clickhouse_test_04001.sql
|
||||
Reference in New Issue
Block a user