Skip to content

Commit

Permalink
Modified the error handling to make it more flexible (#833)
Browse files Browse the repository at this point in the history
* Made error handling more flexible

* Fixed a minor issue with a test
  • Loading branch information
yitam authored Aug 20, 2018
1 parent 4452a4d commit 6a688b3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
14 changes: 10 additions & 4 deletions source/shared/core_sqlsrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

Expand Down
30 changes: 28 additions & 2 deletions source/shared/core_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
10 changes: 7 additions & 3 deletions test/functional/sqlsrv/sqlsrv_ae_type_conversion_select.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]);
Expand Down

0 comments on commit 6a688b3

Please sign in to comment.