// pdo error handler for the dbh context. bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, va_list* print_args ) { pdo_dbh_t* dbh = reinterpret_cast<pdo_dbh_t*>( ctx.driver()); SQLSRV_ASSERT( dbh != NULL, "pdo_sqlsrv_handle_dbh_error: Null dbh passed" ); sqlsrv_error_auto_ptr error; if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) { core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args ); } else { bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC ); SQLSRV_ASSERT( err == true, "No ODBC error was found" ); } SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( dbh->error_code )); strcpy_s( dbh->error_code, sizeof( dbh->error_code ), reinterpret_cast<const char*>( error->sqlstate )); switch( dbh->error_mode ) { case PDO_ERRMODE_EXCEPTION: if( !warning ) { pdo_sqlsrv_throw_exception( error TSRMLS_CC ); } ctx.set_last_error( error ); break; case PDO_ERRMODE_WARNING: if( !warning ) { unsigned int msg_len = strlen( reinterpret_cast<const char*>( error->native_message )) + SQL_SQLSTATE_BUFSIZE + MAX_DIGITS + 1; sqlsrv_malloc_auto_ptr<char> msg; msg = static_cast<char*>( sqlsrv_malloc( msg_len )); core_sqlsrv_format_message( msg, msg_len, WARNING_TEMPLATE, error->sqlstate, error->native_code, error->native_message ); php_error( E_WARNING, msg ); sqlsrv_free( msg ); } ctx.set_last_error( error ); break; case PDO_ERRMODE_SILENT: ctx.set_last_error( error ); break; default: DIE( "Unknown error mode. %1!d!", dbh->error_mode ); break; } // return error ignored = true for warnings. return ( warning ? true : false ); }
// Formats the error message and writes to the php error log. void pdo_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ) { if( (severity & PDO_SQLSRV_G( log_severity )) == 0 ) { return; } DWORD rc = FormatMessage( FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, log_msg, LOG_MSG_SIZE, print_args ); // if an error occurs for FormatMessage, we just output an internal error occurred. if( rc == 0 ) { SQLSRV_STATIC_ASSERT( sizeof( INTERNAL_FORMAT_ERROR ) < sizeof( log_msg )); std::copy( INTERNAL_FORMAT_ERROR, INTERNAL_FORMAT_ERROR + sizeof( INTERNAL_FORMAT_ERROR ), log_msg ); } php_log_err( log_msg TSRMLS_CC ); }
// return an error message for GetLastError using FormatMessage. // this function returns the msg pointer so that it may be used within // another function call such as handle_error const char* get_last_error_message( DWORD last_error ) { if( last_error == 0 ) { last_error = GetLastError(); } DWORD r = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, last_error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), last_err_msg, sizeof( last_err_msg ), NULL ); if( r == 0 ) { SQLSRV_STATIC_ASSERT( sizeof( INTERNAL_FORMAT_ERROR ) < sizeof( last_err_msg )); std::copy( INTERNAL_FORMAT_ERROR, INTERNAL_FORMAT_ERROR + sizeof( INTERNAL_FORMAT_ERROR ), last_err_msg ); } return last_err_msg; }