mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Merge pull request #26172 from ClickHouse/exception_id
Add error id to exceptions
This commit is contained in:
commit
38dfe1fc0a
@ -302,26 +302,9 @@ private:
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
bool print_stack_trace = config().getBool("stacktrace", false);
|
||||
bool print_stack_trace = config().getBool("stacktrace", false) && e.code() != ErrorCodes::NETWORK_ERROR;
|
||||
|
||||
std::string text = e.displayText();
|
||||
|
||||
/** If exception is received from server, then stack trace is embedded in message.
|
||||
* If exception is thrown on client, then stack trace is in separate field.
|
||||
*/
|
||||
|
||||
auto embedded_stack_trace_pos = text.find("Stack trace");
|
||||
if (std::string::npos != embedded_stack_trace_pos && !print_stack_trace)
|
||||
text.resize(embedded_stack_trace_pos);
|
||||
|
||||
std::cerr << "Code: " << e.code() << ". " << text << std::endl << std::endl;
|
||||
|
||||
/// Don't print the stack trace on the client if it was logged on the server.
|
||||
/// Also don't print the stack trace in case of network errors.
|
||||
if (print_stack_trace && e.code() != ErrorCodes::NETWORK_ERROR && std::string::npos == embedded_stack_trace_pos)
|
||||
{
|
||||
std::cerr << "Stack trace:" << std::endl << e.getStackTraceString();
|
||||
}
|
||||
std::cerr << getExceptionMessage(e, print_stack_trace, true) << std::endl << std::endl;
|
||||
|
||||
/// If exception code isn't zero, we should return non-zero return code anyway.
|
||||
return e.code() ? e.code() : -1;
|
||||
@ -700,17 +683,10 @@ private:
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
// We don't need to handle the test hints in the interactive
|
||||
// mode.
|
||||
std::cerr << std::endl
|
||||
<< "Exception on client:" << std::endl
|
||||
<< "Code: " << e.code() << ". " << e.displayText() << std::endl;
|
||||
|
||||
if (config().getBool("stacktrace", false))
|
||||
std::cerr << "Stack trace:" << std::endl << e.getStackTraceString() << std::endl;
|
||||
|
||||
std::cerr << std::endl;
|
||||
/// We don't need to handle the test hints in the interactive mode.
|
||||
|
||||
bool print_stack_trace = config().getBool("stacktrace", false);
|
||||
std::cerr << "Exception on client:" << std::endl << getExceptionMessage(e, print_stack_trace, true) << std::endl << std::endl;
|
||||
client_exception = std::make_unique<Exception>(e);
|
||||
}
|
||||
|
||||
@ -1007,18 +983,11 @@ private:
|
||||
{
|
||||
if (server_exception)
|
||||
{
|
||||
std::string text = server_exception->displayText();
|
||||
auto embedded_stack_trace_pos = text.find("Stack trace");
|
||||
if (std::string::npos != embedded_stack_trace_pos && !config().getBool("stacktrace", false))
|
||||
{
|
||||
text.resize(embedded_stack_trace_pos);
|
||||
}
|
||||
bool print_stack_trace = config().getBool("stacktrace", false);
|
||||
std::cerr << "Received exception from server (version " << server_version << "):" << std::endl
|
||||
<< "Code: " << server_exception->code() << ". " << text << std::endl;
|
||||
<< getExceptionMessage(*server_exception, print_stack_trace, true) << std::endl;
|
||||
if (is_interactive)
|
||||
{
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (client_exception)
|
||||
@ -1477,8 +1446,7 @@ private:
|
||||
{
|
||||
// Just report it, we'll terminate below.
|
||||
fmt::print(stderr,
|
||||
"Error while reconnecting to the server: Code: {}: {}\n",
|
||||
getCurrentExceptionCode(),
|
||||
"Error while reconnecting to the server: {}\n",
|
||||
getCurrentExceptionMessage(true));
|
||||
|
||||
assert(!connection->isConnected());
|
||||
@ -2664,8 +2632,7 @@ public:
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
std::string text = e.displayText();
|
||||
std::cerr << "Code: " << e.code() << ". " << text << std::endl;
|
||||
std::cerr << getExceptionMessage(e, false) << std::endl;
|
||||
std::cerr << "Table №" << i << std::endl << std::endl;
|
||||
/// Avoid the case when error exit code can possibly overflow to normal (zero).
|
||||
auto exit_code = e.code() % 256;
|
||||
@ -2810,8 +2777,7 @@ int mainEntryClickHouseClient(int argc, char ** argv)
|
||||
}
|
||||
catch (const DB::Exception & e)
|
||||
{
|
||||
std::string text = e.displayText();
|
||||
std::cerr << "Code: " << e.code() << ". " << text << std::endl;
|
||||
std::cerr << DB::getExceptionMessage(e, false) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
catch (...)
|
||||
|
@ -313,7 +313,7 @@ std::string getCurrentExceptionMessage(bool with_stacktrace, bool check_embedded
|
||||
try
|
||||
{
|
||||
stream << "Poco::Exception. Code: " << ErrorCodes::POCO_EXCEPTION << ", e.code() = " << e.code()
|
||||
<< ", e.displayText() = " << e.displayText()
|
||||
<< ", " << e.displayText()
|
||||
<< (with_stacktrace ? ", Stack trace (when copying this message, always include the lines below):\n\n" + getExceptionStackTraceString(e) : "")
|
||||
<< (with_extra_info ? getExtraExceptionInfo(e) : "")
|
||||
<< " (version " << VERSION_STRING << VERSION_OFFICIAL << ")";
|
||||
@ -433,7 +433,12 @@ std::string getExceptionMessage(const Exception & e, bool with_stacktrace, bool
|
||||
}
|
||||
}
|
||||
|
||||
stream << "Code: " << e.code() << ", e.displayText() = " << text;
|
||||
stream << "Code: " << e.code() << ". " << text;
|
||||
|
||||
if (!text.empty() && text.back() != '.')
|
||||
stream << '.';
|
||||
|
||||
stream << " (" << ErrorCodes::getName(e.code()) << ")";
|
||||
|
||||
if (with_stacktrace && !has_embedded_stack_trace)
|
||||
stream << ", Stack trace (when copying this message, always include the lines below):\n\n" << e.getStackTraceString();
|
||||
|
@ -1150,7 +1150,7 @@ namespace
|
||||
{
|
||||
io.onException();
|
||||
|
||||
LOG_ERROR(log, "Code: {}, e.displayText() = {}, Stack trace:\n\n{}", exception.code(), exception.displayText(), exception.getStackTraceString());
|
||||
LOG_ERROR(log, getExceptionMessage(exception, true));
|
||||
|
||||
if (responder && !responder_finished)
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ void TCPHandler::runImpl()
|
||||
if (!DatabaseCatalog::instance().isDatabaseExist(default_database))
|
||||
{
|
||||
Exception e("Database " + backQuote(default_database) + " doesn't exist", ErrorCodes::UNKNOWN_DATABASE);
|
||||
LOG_ERROR(log, "Code: {}, e.displayText() = {}, Stack trace:\n\n{}", e.code(), e.displayText(), e.getStackTraceString());
|
||||
LOG_ERROR(log, getExceptionMessage(e, true));
|
||||
sendException(e, connection_context->getSettingsRef().calculate_text_stack_trace);
|
||||
return;
|
||||
}
|
||||
@ -422,7 +422,7 @@ void TCPHandler::runImpl()
|
||||
}
|
||||
|
||||
const auto & e = *exception;
|
||||
LOG_ERROR(log, "Code: {}, e.displayText() = {}, Stack trace:\n\n{}", e.code(), e.displayText(), e.getStackTraceString());
|
||||
LOG_ERROR(log, getExceptionMessage(e, true));
|
||||
sendException(*exception, send_exception_with_stack_trace);
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ SELECTS_SQL = {
|
||||
"ORDER BY node"),
|
||||
}
|
||||
|
||||
EXCEPTION_NETWORK = 'e.displayText() = DB::NetException: '
|
||||
EXCEPTION_NETWORK = 'DB::NetException: '
|
||||
EXCEPTION_TIMEOUT = 'Timeout exceeded while reading from socket ('
|
||||
EXCEPTION_CONNECT = 'Timeout: connect timed out: '
|
||||
|
||||
@ -76,13 +76,13 @@ def _check_exception(exception, expected_tries=3):
|
||||
|
||||
for i, line in enumerate(lines[3:3 + expected_tries]):
|
||||
expected_lines = (
|
||||
'Code: 209, ' + EXCEPTION_NETWORK + EXCEPTION_TIMEOUT,
|
||||
'Code: 209, ' + EXCEPTION_NETWORK + EXCEPTION_CONNECT,
|
||||
'Code: 209. ' + EXCEPTION_NETWORK + EXCEPTION_TIMEOUT,
|
||||
'Code: 209. ' + EXCEPTION_NETWORK + EXCEPTION_CONNECT,
|
||||
EXCEPTION_TIMEOUT,
|
||||
)
|
||||
|
||||
assert any(line.startswith(expected) for expected in expected_lines), \
|
||||
'Unexpected exception at one of the connection attempts'
|
||||
'Unexpected exception "{}" at one of the connection attempts'.format(line)
|
||||
|
||||
assert lines[3 + expected_tries] == '', 'Wrong number of connect attempts'
|
||||
|
||||
|
@ -95,8 +95,11 @@ def test_mysql_client(started_cluster):
|
||||
'''.format(host=started_cluster.get_instance_ip('node'), port=server_port), demux=True)
|
||||
|
||||
assert stdout.decode() == 'count()\n1\n'
|
||||
assert stderr[0:182].decode() == "mysql: [Warning] Using a password on the command line interface can be insecure.\n" \
|
||||
"ERROR 81 (00000) at line 1: Code: 81, e.displayText() = DB::Exception: Database system2 doesn't exist"
|
||||
expected_msg = '\n'.join([
|
||||
"mysql: [Warning] Using a password on the command line interface can be insecure.",
|
||||
"ERROR 81 (00000) at line 1: Code: 81. DB::Exception: Database system2 doesn't exist",
|
||||
])
|
||||
assert stderr[:len(expected_msg)].decode() == expected_msg
|
||||
|
||||
code, (stdout, stderr) = started_cluster.mysql_client_container.exec_run('''
|
||||
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
||||
@ -122,8 +125,11 @@ def test_mysql_client_exception(started_cluster):
|
||||
-e "CREATE TABLE default.t1_remote_mysql AS mysql('127.0.0.1:10086','default','t1_local','default','');"
|
||||
'''.format(host=started_cluster.get_instance_ip('node'), port=server_port), demux=True)
|
||||
|
||||
assert stderr[0:258].decode() == "mysql: [Warning] Using a password on the command line interface can be insecure.\n" \
|
||||
"ERROR 1000 (00000) at line 1: Poco::Exception. Code: 1000, e.code() = 0, e.displayText() = Exception: Connections to all replicas failed: default@127.0.0.1:10086 as user default"
|
||||
expected_msg = '\n'.join([
|
||||
"mysql: [Warning] Using a password on the command line interface can be insecure.",
|
||||
"ERROR 1000 (00000) at line 1: Poco::Exception. Code: 1000, e.code() = 0, Exception: Connections to all replicas failed: default@127.0.0.1:10086 as user default",
|
||||
])
|
||||
assert stderr[:len(expected_msg)].decode() == expected_msg
|
||||
|
||||
|
||||
def test_mysql_affected_rows(started_cluster):
|
||||
@ -328,8 +334,7 @@ def test_python_client(started_cluster):
|
||||
with pytest.raises(pymysql.InternalError) as exc_info:
|
||||
client.query('select name from tables')
|
||||
|
||||
assert exc_info.value.args[1][
|
||||
0:77] == "Code: 60, e.displayText() = DB::Exception: Table default.tables doesn't exist"
|
||||
assert exc_info.value.args[1].startswith("Code: 60. DB::Exception: Table default.tables doesn't exist"), exc_info.value.args[1]
|
||||
|
||||
cursor = client.cursor(pymysql.cursors.DictCursor)
|
||||
cursor.execute("select 1 as a, 'тест' as b")
|
||||
@ -348,8 +353,7 @@ def test_python_client(started_cluster):
|
||||
with pytest.raises(pymysql.InternalError) as exc_info:
|
||||
client.query('select name from tables')
|
||||
|
||||
assert exc_info.value.args[1][
|
||||
0:77] == "Code: 60, e.displayText() = DB::Exception: Table default.tables doesn't exist"
|
||||
assert exc_info.value.args[1].startswith("Code: 60. DB::Exception: Table default.tables doesn't exist"), exc_info.value.args[1]
|
||||
|
||||
cursor = client.cursor(pymysql.cursors.DictCursor)
|
||||
cursor.execute("select 1 as a, 'тест' as b")
|
||||
@ -360,7 +364,7 @@ def test_python_client(started_cluster):
|
||||
with pytest.raises(pymysql.InternalError) as exc_info:
|
||||
client.select_db('system2')
|
||||
|
||||
assert exc_info.value.args[1][0:73] == "Code: 81, e.displayText() = DB::Exception: Database system2 doesn't exist"
|
||||
assert exc_info.value.args[1].startswith("Code: 81. DB::Exception: Database system2 doesn't exist"), exc_info.value.args[1]
|
||||
|
||||
cursor = client.cursor(pymysql.cursors.DictCursor)
|
||||
cursor.execute('CREATE DATABASE x')
|
||||
|
@ -78,7 +78,7 @@ def test_no_stall(started_cluster):
|
||||
"""
|
||||
SELECT count()
|
||||
FROM system.replication_queue
|
||||
WHERE last_exception LIKE '%e.displayText() = Timeout%'
|
||||
WHERE last_exception LIKE '%Timeout%'
|
||||
AND last_exception NOT LIKE '%connect timed out%'
|
||||
""").strip())
|
||||
|
||||
|
@ -66,7 +66,7 @@ def get_kafka_producer(port, serializer, retries):
|
||||
except Exception as e:
|
||||
errors += [str(e)]
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
raise Exception("Connection not establised, {}".format(errors))
|
||||
|
||||
def producer_serializer(x):
|
||||
@ -1339,7 +1339,7 @@ def test_librdkafka_compression(kafka_cluster):
|
||||
|
||||
Example of corruption:
|
||||
|
||||
2020.12.10 09:59:56.831507 [ 20 ] {} <Error> void DB::StorageKafka::threadFunc(size_t): Code: 27, e.displayText() = DB::Exception: Cannot parse input: expected '"' before: 'foo"}': (while reading the value of key value): (at row 1)
|
||||
2020.12.10 09:59:56.831507 [ 20 ] {} <Error> void DB::StorageKafka::threadFunc(size_t): Code: 27. DB::Exception: Cannot parse input: expected '"' before: 'foo"}': (while reading the value of key value): (at row 1)
|
||||
|
||||
To trigger this regression there should duplicated messages
|
||||
|
||||
|
@ -18,7 +18,7 @@ function ch_url() {
|
||||
|
||||
# Check correct exceptions handling
|
||||
|
||||
exception_pattern="displayText() = DB::Exception:[[:print:]]*"
|
||||
exception_pattern="DB::Exception:[[:print:]]*"
|
||||
|
||||
function check_only_exception() {
|
||||
local res
|
||||
|
@ -89,7 +89,7 @@ idx10 ['This','is','a','test']
|
||||
23.00
|
||||
24.00
|
||||
=== Try load data from datapage_v2.snappy.parquet
|
||||
Code: 33. DB::ParsingEx---tion: Error while reading Parquet data: IOError: Not yet implemented: Unsupported encoding.: data for INSERT was parsed from stdin
|
||||
Code: 33. DB::ParsingEx---tion: Error while reading Parquet data: IOError: Not yet implemented: Unsupported encoding.: data for INSERT was parsed from stdin. (CANNOT_READ_ALL_DATA)
|
||||
|
||||
=== Try load data from dict-page-offset-zero.parquet
|
||||
1552
|
||||
|
@ -1,25 +1,25 @@
|
||||
none
|
||||
Received exception from server:
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57, e.displayText() = Error: Table default.throw already exists
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57. Error: Table default.throw already exists. (TABLE_ALREADY_EXISTS)
|
||||
Received exception from server:
|
||||
Code: 159. Error: Received from localhost:9000. Error: Watching task <task> is executing longer than distributed_ddl_task_timeout (=8) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.
|
||||
Code: 159. Error: Received from localhost:9000. Error: Watching task <task> is executing longer than distributed_ddl_task_timeout (=8) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.(TIMEOUT_EXCEEDED)
|
||||
throw
|
||||
localhost 9000 0 0 0
|
||||
localhost 9000 57 Code: 57, e.displayText() = Error: Table default.throw already exists. 0 0
|
||||
localhost 9000 57 Code: 57. Error: Table default.throw already exists. (TABLE_ALREADY_EXISTS) 0 0
|
||||
Received exception from server:
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57, e.displayText() = Error: Table default.throw already exists
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57. Error: Table default.throw already exists. (TABLE_ALREADY_EXISTS)
|
||||
localhost 9000 0 1 0
|
||||
Received exception from server:
|
||||
Code: 159. Error: Received from localhost:9000. Error: Watching task <task> is executing longer than distributed_ddl_task_timeout (=8) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.
|
||||
Code: 159. Error: Received from localhost:9000. Error: Watching task <task> is executing longer than distributed_ddl_task_timeout (=8) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.(TIMEOUT_EXCEEDED)
|
||||
null_status_on_timeout
|
||||
localhost 9000 0 0 0
|
||||
localhost 9000 57 Code: 57, e.displayText() = Error: Table default.null_status already exists. 0 0
|
||||
localhost 9000 57 Code: 57. Error: Table default.null_status already exists. (TABLE_ALREADY_EXISTS) 0 0
|
||||
Received exception from server:
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57, e.displayText() = Error: Table default.null_status already exists
|
||||
Code: 57. Error: Received from localhost:9000. Error: There was an error on [localhost:9000]: Code: 57. Error: Table default.null_status already exists. (TABLE_ALREADY_EXISTS)
|
||||
localhost 9000 0 1 0
|
||||
localhost 1 \N \N 1 0
|
||||
never_throw
|
||||
localhost 9000 0 0 0
|
||||
localhost 9000 57 Code: 57, e.displayText() = Error: Table default.never_throw already exists. 0 0
|
||||
localhost 9000 57 Code: 57. Error: Table default.never_throw already exists. (TABLE_ALREADY_EXISTS) 0 0
|
||||
localhost 9000 0 1 0
|
||||
localhost 1 \N \N 1 0
|
||||
|
@ -13,4 +13,4 @@ yml
|
||||
yaml
|
||||
2
|
||||
ini
|
||||
Code: 347. Unknown format of '/config_default.ini' config
|
||||
Code: 347. Unknown format of '/config_default.ini' config. (CANNOT_LOAD_CONFIG)
|
||||
|
Loading…
Reference in New Issue
Block a user