Modified the error handling to make it more flexible (#833)

* Made error handling more flexible

* Fixed a minor issue with a test
This commit is contained in:
Jenny Tam 2018-08-20 14:51:33 -07:00 committed by GitHub
parent 4452a4d61b
commit 6a688b3727
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 9 deletions

View file

@ -175,7 +175,7 @@ const int SQL_SERVER_MAX_TYPE_SIZE = 0;
const int SQL_SERVER_MAX_PARAMS = 2100;
// increase the maximum message length to accommodate for the long error returned for operand type clash
// or for conversion of a long string
const int SQL_MAX_ERROR_MESSAGE_LENGTH = SQL_MAX_MESSAGE_LENGTH * 8;
const int SQL_MAX_ERROR_MESSAGE_LENGTH = SQL_MAX_MESSAGE_LENGTH * 2;
// max size of a date time string when converting from a DateTime object to a string
const int MAX_DATETIME_STRING_LEN = 256;
@ -1889,14 +1889,20 @@ namespace core {
// and return a more helpful message prepended to the ODBC errors if that error occurs
if( !SQL_SUCCEEDED( r )) {
SQLCHAR err_msg[SQL_MAX_ERROR_MESSAGE_LENGTH + 1] = {'\0'};
SQLCHAR err_msg[SQL_MAX_MESSAGE_LENGTH + 1] = {'\0'};
SQLSMALLINT len = 0;
SQLRETURN rtemp = ::SQLGetDiagField( stmt->handle_type(), stmt->handle(), 1, SQL_DIAG_MESSAGE_TEXT,
err_msg, SQL_MAX_ERROR_MESSAGE_LENGTH, &len );
err_msg, SQL_MAX_MESSAGE_LENGTH, &len );
if (rtemp == SQL_SUCCESS_WITH_INFO && len > SQL_MAX_MESSAGE_LENGTH) {
// if the error message is this long, then it must not be the mars message
// defined as ODBC_CONNECTION_BUSY_ERROR -- so return here and continue the
// regular error handling
return;
}
CHECK_SQL_ERROR_OR_WARNING( rtemp, stmt ) {
throw CoreException();
}

View file

@ -265,10 +265,36 @@ bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_nu
// We need to calculate number of characters
SQLINTEGER wsqlstate_len = sizeof( wsqlstate ) / sizeof( SQLWCHAR );
SQLLEN sqlstate_len = 0;
convert_string_from_utf16(enc, wsqlstate, wsqlstate_len, (char**)&error->sqlstate, sqlstate_len);
convert_string_from_utf16(enc, wsqlstate, wsqlstate_len, (char**)&error->sqlstate, sqlstate_len);
SQLLEN message_len = 0;
convert_string_from_utf16(enc, wnative_message, wmessage_len, (char**)&error->native_message, message_len);
if (r == SQL_SUCCESS_WITH_INFO && wmessage_len > SQL_MAX_ERROR_MESSAGE_LENGTH) {
// note that wmessage_len is the number of characters required for the error message --
// create a new buffer big enough for this lengthy error message
sqlsrv_malloc_auto_ptr<SQLWCHAR> wnative_message_str;
SQLSMALLINT expected_len = wmessage_len * sizeof(SQLWCHAR);
SQLSMALLINT returned_len = 0;
wnative_message_str = reinterpret_cast<SQLWCHAR*>(sqlsrv_malloc(expected_len));
memset(wnative_message_str, '\0', expected_len);
SQLRETURN rtemp = ::SQLGetDiagFieldW(h_type, h, record_number, SQL_DIAG_MESSAGE_TEXT, wnative_message_str, wmessage_len, &returned_len);
if (!SQL_SUCCEEDED(rtemp) || returned_len != expected_len) {
// something went wrong
return false;
}
convert_string_from_utf16(enc, wnative_message_str, wmessage_len, (char**)&error->native_message, message_len);
} else {
convert_string_from_utf16(enc, wnative_message, wmessage_len, (char**)&error->native_message, message_len);
}
if (message_len == 0 && error->native_message == NULL) {
// something went wrong
return false;
}
break;
}

View file

@ -29,8 +29,10 @@ function checkErrors(&$convError)
$convError[0][1] != '8114' and
$convError[0][1] != '8169') {
print_r($convError);
fatalError("Conversion failed with unexpected error message. i=$i, j=$j, v=$v\n");
}
return false;
}
return true;
}
// Build the select queries. We want every combination of types for conversion
@ -202,7 +204,9 @@ for ($v = 0; $v < sizeof($values); ++$v) {
if ($stmt == false) {
$convError = sqlsrv_errors();
checkErrors($convError);
if (!checkErrors($convError)) {
fatalError("Conversion failed with unexpected error message. i=$i, j=$j, v=$v\n");
}
if (AE\isDataEncrypted()) {
$stmtAE = sqlsrv_query($conn, $selectQueryAE[$i][$j]);