Kaja
Kaja

Reputation: 3057

Try-Catch doesn't catch exception

I would like to catch an exception, which occures in my code using Try/Catch like this:

try
{
//my code
}
catch(std::exception &e)
   {
       std::wcout <<"An exception occured"<<" "<<e.what();
   }

but such a structure dosn't catch the exception in my code. I recieve an exception from Visual studio in this line:

retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN);

and not from my try/catch.

here you can see my whole code:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include<tchar.h>
#include<iostream>
#include<sqlncli.h>
#include<exception>
using namespace std;

SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC;
SQLHSTMT hstmt2 = SQL_NULL_HSTMT;

void Cleanup() {
   if (hstmt2 != SQL_NULL_HSTMT)
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);

   if (hdbc1 != SQL_NULL_HDBC) {
      SQLDisconnect(hdbc1);
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   }

   if (hdbc2 != SQL_NULL_HDBC) {
      SQLDisconnect(hdbc2);
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
   }

   if (henv != SQL_NULL_HENV)
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

int main() {
try
{
   RETCODE retcode;

   // BCP variables.
   char *terminator = "\0";

   // bcp_done takes a different format return code because it returns number of rows bulk copied
   // after the last bcp_batch call.
   DBINT cRowsDone = 0;

   // Set up separate return code for bcp_sendrow so it is not using the same retcode as SQLFetch.
   RETCODE SendRet;



   // Allocate the ODBC environment and save handle.
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(Env) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Notify ODBC that this is an ODBC 3.0 app.
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
      Cleanup();
      return(9);    
   }

   // Allocate ODBC connection handle, set bulk copy mode, and connect.
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLSetConnectAttr(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   // sample uses Integrated Security, create the SQL Server DSN using Windows NT authentication
   SQLWCHAR dsn[30] = L"mssqltest"; //Name DNS
   SQLWCHAR user[10] = L"di_test";
   SQLWCHAR pass[10] = L"di_test";
 //  SQLWCHAR tb[20]=L"information1";

   retcode = SQLConnectW(hdbc1, (SQLWCHAR *)dsn, SQL_NTS, (SQLWCHAR *) user, SQL_NTS, (SQLWCHAR *) pass, SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLConnect() Failed\n\n");
      Cleanup();
      return(9);
   }
    //  TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);
   // Initialize the bulk copy.



   retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN);
  /* TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);*/
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("bcp_init(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   //Define our array
   DBINT custIDs[] ={1,2,3,4};

   // Bind the program variables for the bulk copy.
   if( bcp_bind(hdbc1, (BYTE *)&custIDs, 0, sizeof(DBINT), NULL,0, SQLINT4, 2)==FAIL)
   {
       retcode=-1;
   }
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)  ) {
      printf("bcp_bind(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Could normally use strlen to calculate the bcp_bind cbTerm parameter, but this terminator 
   // is a null byte (\0), which gives strlen a value of 0. Explicitly give cbTerm a value of 1.
   if( bcp_bind(hdbc1,(LPCBYTE) custIDs, 2, SQL_VARLEN_DATA, NULL,0, SQL_C_NUMERIC, 3)==FAIL)
   {
       retcode=-1;
   }
   if ( (retcode != SUCCEED) ) {
      printf("bcp_bind(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }


   if ( (SendRet = bcp_sendrow(hdbc1) ) != SUCCEED ) {
         printf("bcp_sendrow(hdbc1) Failed\n\n");
         Cleanup();
         return(9);
      }

   cRowsDone = bcp_done(hdbc1);
   if ( (cRowsDone == -1) ) {
      printf("bcp_done(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }



   printf("Number of rows bulk copied after last bcp_batch call = %d.\n", cRowsDone);

   // Cleanup.
   SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
   SQLDisconnect(hdbc1);
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   SQLDisconnect(hdbc2);
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
   }
   catch(std::exception &e)
   {
       std::wcout <<"An exception occured"<<" "<<e.what();
   }
 }

Upvotes: 1

Views: 5676

Answers (2)

dascandy
dascandy

Reputation: 7302

You're not seeing a C++ exception. This is what Microsoft calls a SEH exception, which is actually a program crash. You can catch those (search on MSDN for __try and __except) but in general this is like the Java NullPointerException - it's a programming error, and no error handling is going to fix that.

Also, Visual Studio, if set to "break on all exceptions", will break when an exception occurs that will be handled in a try/catch too. If you just continue execution, it'll go to the corresponding catch & be handled. If this is what happens, turn off the "break on all exceptions". It will stop anyway on unhandled ones.

Upvotes: 8

Paolo M
Paolo M

Reputation: 12777

C++ is not Java. There is no such thing as a universal base class exception, so std::exception is just a base class for all exceptions thrown by the Standard Library.

If you want to catch any exception (and not any strange error that could happen), you can use catch(...).

As shown by SingerOfTheFall's comment, you can use C++11 std::current_exception to inspect the exception object.

Upvotes: 4

Related Questions