Fix http exception codes.

This commit is contained in:
kothiga 2024-02-21 10:53:49 -08:00
parent c309e643ea
commit 692b31e467
No known key found for this signature in database
4 changed files with 90 additions and 45 deletions

View File

@ -884,6 +884,9 @@ void HTTPHandler::processQuery(
{
if (settings.http_write_exception_in_output_format && output_format.supportsWritingException())
{
ExecutionStatus status = ExecutionStatus::fromCurrentException("", false);
formatExceptionForClient(status.code, request, response, used_output);
output_format.setException(getCurrentExceptionMessage(false));
output_format.finalize();
used_output.exception_is_written = true;
@ -916,31 +919,7 @@ void HTTPHandler::trySendExceptionToClient(
const std::string & s, int exception_code, HTTPServerRequest & request, HTTPServerResponse & response, Output & used_output)
try
{
if (used_output.out_holder)
used_output.out_holder->setExceptionCode(exception_code);
else
response.set("X-ClickHouse-Exception-Code", toString<int>(exception_code));
/// FIXME: make sure that no one else is reading from the same stream at the moment.
/// If HTTP method is POST and Keep-Alive is turned on, we should read the whole request body
/// to avoid reading part of the current request body in the next request.
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST
&& response.getKeepAlive()
&& exception_code != ErrorCodes::HTTP_LENGTH_REQUIRED
&& !request.getStream().eof())
{
request.getStream().ignoreAll();
}
if (exception_code == ErrorCodes::REQUIRED_PASSWORD)
{
response.requireAuthentication("ClickHouse server HTTP API");
}
else
{
response.setStatusAndReason(exceptionCodeToHTTPStatus(exception_code));
}
formatExceptionForClient(exception_code, request, response, used_output);
if (!used_output.out_holder && !used_output.exception_is_written)
{
@ -1001,6 +980,28 @@ catch (...)
}
}
void HTTPHandler::formatExceptionForClient(int exception_code, HTTPServerRequest & request, HTTPServerResponse & response, Output & used_output)
{
if (used_output.out_holder)
used_output.out_holder->setExceptionCode(exception_code);
else
response.set("X-ClickHouse-Exception-Code", toString<int>(exception_code));
/// FIXME: make sure that no one else is reading from the same stream at the moment.
/// If HTTP method is POST and Keep-Alive is turned on, we should read the whole request body
/// to avoid reading part of the current request body in the next request.
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST && response.getKeepAlive()
&& exception_code != ErrorCodes::HTTP_LENGTH_REQUIRED && !request.getStream().eof())
{
request.getStream().ignoreAll();
}
if (exception_code == ErrorCodes::REQUIRED_PASSWORD)
response.requireAuthentication("ClickHouse server HTTP API");
else
response.setStatusAndReason(exceptionCodeToHTTPStatus(exception_code));
}
void HTTPHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse & response, const ProfileEvents::Event & write_event)
{

View File

@ -148,6 +148,12 @@ private:
HTTPServerResponse & response,
Output & used_output);
void formatExceptionForClient(
int exception_code,
HTTPServerRequest & request,
HTTPServerResponse & response,
Output & used_output);
static void pushDelayedResults(Output & used_output);
};

View File

@ -1,25 +1,47 @@
SELECT missing column WITH default_format=JSON
404NotFound
Content-Type:application/json;charset=UTF-8
X-ClickHouse-Ex---tion-Code:47
"exception":"Code:47.
INSERT WITH default_format=JSON
Content-Type:application/json;charset=UTF-8
"exception":"Code:62.
501NotImplemented
Content-Type:application/json;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
"exception":"Code:48.
INSERT WITH default_format=XML
Content-Type:application/xml;charset=UTF-8
<exception>Code:62.DB::Ex---tion:
501NotImplemented
Content-Type:application/xml;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
<exception>Code:48.DB::Ex---tion:
INSERT WITH default_format=BADFORMAT
Content-Type:text/plain;charset=UTF-8
X-ClickHouse-Ex---tion-Code:62
Code:62.DB::Ex---tion:
501NotImplemented
Content-Type:text/plain;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
Code:48.DB::Ex---tion:
SELECT missing column WITH X-ClickHouse-Format: JSON
404NotFound
Content-Type:application/json;charset=UTF-8
X-ClickHouse-Ex---tion-Code:47
"exception":"Code:47.
INSERT WITH X-ClickHouse-Format: JSON
Content-Type:application/json;charset=UTF-8
"exception":"Code:62.
501NotImplemented
Content-Type:application/json;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
"exception":"Code:48.
INSERT WITH X-ClickHouse-Format: XML
Content-Type:application/xml;charset=UTF-8
<exception>Code:62.DB::Ex---tion:
501NotImplemented
Content-Type:application/xml;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
<exception>Code:48.DB::Ex---tion:
INSERT WITH X-ClickHouse-Format: BADFORMAT
Content-Type:text/plain;charset=UTF-8
X-ClickHouse-Ex---tion-Code:62
Code:62.DB::Ex---tion:
501NotImplemented
Content-Type:text/plain;charset=UTF-8
X-ClickHouse-Ex---tion-Code:48
Code:48.DB::Ex---tion:

View File

@ -6,28 +6,44 @@ CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
CH_URL="$CLICKHOUSE_URL&http_write_exception_in_output_format=1"
echo "SELECT missing column WITH default_format=JSON"
echo "SELECT x FROM system.numbers LIMIT 1;"\
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=JSON" -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH default_format=JSON"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=JSON" -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=JSON" -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH default_format=XML"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=XML" -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=XML" -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH default_format=BADFORMAT"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=BADFORMAT" -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}&default_format=BADFORMAT" -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "SELECT missing column WITH X-ClickHouse-Format: JSON"
echo "SELECT x FROM system.numbers LIMIT 1;"\
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: JSON' -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH X-ClickHouse-Format: JSON"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: JSON' -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: JSON' -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH X-ClickHouse-Format: XML"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: XML' -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: XML' -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'
echo ""
echo "INSERT WITH X-ClickHouse-Format: BADFORMAT"
echo "INSERT INTO system.numbers Select * from numbers(10);" \
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: BADFORMAT' -i | grep 'xception\|Content-Type' | sed 's/Exception/Ex---tion/' | awk '{ print $1 $2 $3 }'
| ${CLICKHOUSE_CURL} -sS "${CH_URL}" -H 'X-ClickHouse-Format: BADFORMAT' -i --data-binary @- \
| grep 'HTTP/1.1\|xception\|Content-Type' | sed 's/Exception/Ex---tion/;s/HTTP\/1.1//;s/\r//' | awk '{ print $1 $2 $3 }'